600
536
('a-id', 'a', True),
601
537
('b-id', 'b', True),
602
538
], [(r[0], r[1], r[2]) for r in dlg._files_store])
604
def test_specific_files(self):
605
tree = self.make_branch_and_tree('tree')
606
self.build_tree(['tree/a', 'tree/b/'])
607
tree.add(['a', 'b'], ['a-id', 'b-id'])
609
dlg = commit.CommitDialog(tree)
610
self.assertEqual((['a', 'b'], []), dlg._get_specific_files())
612
dlg._commit_selected_radio.set_active(True)
613
dlg._toggle_commit(None, 0, dlg._files_store)
614
self.assertEqual(([], []), dlg._get_specific_files())
616
dlg._toggle_commit(None, 1, dlg._files_store)
617
self.assertEqual((['a'], []), dlg._get_specific_files())
619
def test_specific_files_with_messages(self):
620
tree = self.make_branch_and_tree('tree')
621
tree.branch.get_config().set_user_option('per_file_commits', 'true')
622
self.build_tree(['tree/a_file', 'tree/b_dir/'])
623
tree.add(['a_file', 'b_dir'], ['1a-id', '0b-id'])
625
dlg = commit.CommitDialog(tree)
626
dlg._commit_selected_radio.set_active(True)
627
self.assertEqual((['a_file', 'b_dir'], []), dlg._get_specific_files())
629
dlg._treeview_files.set_cursor((1,))
630
dlg._set_file_commit_message('Test\nmessage\nfor a_file\n')
631
dlg._treeview_files.set_cursor((2,))
632
dlg._set_file_commit_message('message\nfor b_dir\n')
634
self.assertEqual((['a_file', 'b_dir'],
635
[{'path':'a_file', 'file_id':'1a-id',
636
'message':'Test\nmessage\nfor a_file\n'},
637
{'path':'b_dir', 'file_id':'0b-id',
638
'message':'message\nfor b_dir\n'},
639
]), dlg._get_specific_files())
641
dlg._toggle_commit(None, 1, dlg._files_store)
642
self.assertEqual((['b_dir'],
643
[{'path':'b_dir', 'file_id':'0b-id',
644
'message':'message\nfor b_dir\n'},
645
]), dlg._get_specific_files())
648
class TestCommitDialog_Commit(tests.TestCaseWithTransport):
649
"""Tests on the actual 'commit' button being pushed."""
651
def _set_question_yes(self, dlg):
652
"""Set the dialog to answer YES to any questions."""
654
def _question_yes(*args):
655
self.questions.append(args)
656
self.questions.append('YES')
657
return gtk.RESPONSE_YES
658
dlg._question_dialog = _question_yes
660
def _set_question_no(self, dlg):
661
"""Set the dialog to answer NO to any questions."""
663
def _question_no(*args):
664
self.questions.append(args)
665
self.questions.append('NO')
666
return gtk.RESPONSE_NO
667
dlg._question_dialog = _question_no
669
def test_bound_commit_local(self):
670
tree = self.make_branch_and_tree('tree')
671
self.build_tree(['tree/a'])
672
tree.add(['a'], ['a-id'])
673
rev_id1 = tree.commit('one')
675
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
676
self.build_tree(['tree2/b'])
677
tree2.add(['b'], ['b-id'])
678
tree2.branch.bind(tree.branch)
680
dlg = commit.CommitDialog(tree2)
681
# With the check box set, it should only effect the local branch
682
dlg._check_local.set_active(True)
683
dlg._set_global_commit_message('Commit message\n')
686
last_rev = tree2.last_revision()
687
self.assertEqual(last_rev, dlg.committed_revision_id)
688
self.assertEqual(rev_id1, tree.branch.last_revision())
690
def test_bound_commit_both(self):
691
tree = self.make_branch_and_tree('tree')
692
self.build_tree(['tree/a'])
693
tree.add(['a'], ['a-id'])
694
rev_id1 = tree.commit('one')
696
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
697
self.build_tree(['tree2/b'])
698
tree2.add(['b'], ['b-id'])
699
tree2.branch.bind(tree.branch)
701
dlg = commit.CommitDialog(tree2)
702
# With the check box set, it should only effect the local branch
703
dlg._check_local.set_active(False)
704
dlg._set_global_commit_message('Commit message\n')
707
last_rev = tree2.last_revision()
708
self.assertEqual(last_rev, dlg.committed_revision_id)
709
self.assertEqual(last_rev, tree.branch.last_revision())
711
def test_commit_no_message(self):
712
tree = self.make_branch_and_tree('tree')
713
self.build_tree(['tree/a', 'tree/b'])
714
tree.add(['a'], ['a-id'])
715
rev_id = tree.commit('one')
717
tree.add(['b'], ['b-id'])
719
dlg = commit.CommitDialog(tree)
720
self._set_question_no(dlg)
723
[('Commit with an empty message?',
724
'You can describe your commit intent in the message.'),
727
# By saying NO, nothing should be committed.
728
self.assertEqual(rev_id, tree.last_revision())
729
self.assertIs(None, dlg.committed_revision_id)
730
self.assertTrue(dlg._global_message_text_view.get_property('is-focus'))
732
self._set_question_yes(dlg)
736
[('Commit with an empty message?',
737
'You can describe your commit intent in the message.'),
740
committed = tree.last_revision()
741
self.assertNotEqual(rev_id, committed)
742
self.assertEqual(committed, dlg.committed_revision_id)
744
def test_initial_commit(self):
745
tree = self.make_branch_and_tree('tree')
746
self.build_tree(['tree/a'])
747
tree.add(['a'], ['a-id'])
749
dlg = commit.CommitDialog(tree)
750
dlg._set_global_commit_message('Some text\n')
753
last_rev = tree.last_revision()
754
self.assertEqual(last_rev, dlg.committed_revision_id)
755
rev = tree.branch.repository.get_revision(last_rev)
756
self.assertEqual(last_rev, rev.revision_id)
757
self.assertEqual('Some text\n', rev.message)
759
def test_pointless_commit(self):
760
tree = self.make_branch_and_tree('tree')
761
self.build_tree(['tree/a'])
762
tree.add(['a'], ['a-id'])
763
rev_id1 = tree.commit('one')
765
dlg = commit.CommitDialog(tree)
766
dlg._set_global_commit_message('Some text\n')
768
self._set_question_no(dlg)
771
self.assertIs(None, dlg.committed_revision_id)
772
self.assertEqual(rev_id1, tree.last_revision())
774
[('Commit with no changes?',
775
'There are no changes in the working tree.'
776
' Do you want to commit anyway?'),
780
self._set_question_yes(dlg)
783
rev_id2 = tree.last_revision()
784
self.assertEqual(rev_id2, dlg.committed_revision_id)
785
self.assertNotEqual(rev_id1, rev_id2)
787
[('Commit with no changes?',
788
'There are no changes in the working tree.'
789
' Do you want to commit anyway?'),
793
def test_unknowns(self):
794
"""We should check if there are unknown files."""
795
tree = self.make_branch_and_tree('tree')
796
rev_id1 = tree.commit('one')
797
self.build_tree(['tree/a', 'tree/b'])
798
tree.add(['a'], ['a-id'])
800
dlg = commit.CommitDialog(tree)
801
dlg._set_global_commit_message('Some text\n')
802
self._set_question_no(dlg)
806
self.assertIs(None, dlg.committed_revision_id)
807
self.assertEqual(rev_id1, tree.last_revision())
809
[("Commit with unknowns?",
810
"Unknown files exist in the working tree. Commit anyway?"),
814
self._set_question_yes(dlg)
817
rev_id2 = tree.last_revision()
818
self.assertNotEqual(rev_id1, rev_id2)
819
self.assertEqual(rev_id2, dlg.committed_revision_id)
821
[("Commit with unknowns?",
822
"Unknown files exist in the working tree. Commit anyway?"),
826
def test_commit_specific_files(self):
827
tree = self.make_branch_and_tree('tree')
828
rev_id1 = tree.commit('one')
829
self.build_tree(['tree/a', 'tree/b'])
830
tree.add(['a', 'b'], ['a-id', 'b-id'])
832
dlg = commit.CommitDialog(tree)
833
dlg._commit_selected_radio.set_active(True) # enable partial
834
dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
836
dlg._set_global_commit_message('Committing just "a"\n')
839
rev_id2 = dlg.committed_revision_id
840
self.assertIsNot(None, rev_id2)
841
self.assertEqual(rev_id2, tree.last_revision())
843
rt = tree.branch.repository.revision_tree(rev_id2)
844
entries = [(path, ie.file_id) for path, ie in rt.iter_entries_by_dir()
845
if path] # Ignore the root entry
846
self.assertEqual([('a', 'a-id')], entries)
848
def test_commit_partial_no_partial(self):
849
"""Ignore the checkboxes if committing all files."""
850
tree = self.make_branch_and_tree('tree')
851
rev_id1 = tree.commit('one')
852
self.build_tree(['tree/a', 'tree/b'])
853
tree.add(['a', 'b'], ['a-id', 'b-id'])
855
dlg = commit.CommitDialog(tree)
856
dlg._commit_selected_radio.set_active(True) # enable partial
857
dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
859
# Switch back to committing all changes
860
dlg._commit_all_files_radio.set_active(True)
862
dlg._set_global_commit_message('Committing everything\n')
865
rev_id2 = dlg.committed_revision_id
866
self.assertIsNot(None, rev_id2)
867
self.assertEqual(rev_id2, tree.last_revision())
869
rt = tree.branch.repository.revision_tree(rev_id2)
870
entries = [(path, ie.file_id) for path, ie in rt.iter_entries_by_dir()
871
if path] # Ignore the root entry
872
self.assertEqual([('a', 'a-id'), ('b', 'b-id')], entries)
874
def test_commit_no_messages(self):
875
tree = self.make_branch_and_tree('tree')
876
rev_id1 = tree.commit('one')
877
self.build_tree(['tree/a', 'tree/b'])
878
tree.add(['a', 'b'], ['a-id', 'b-id'])
880
dlg = commit.CommitDialog(tree)
881
dlg._set_global_commit_message('Simple commit\n')
884
rev = tree.branch.repository.get_revision(dlg.committed_revision_id)
885
self.failIf('file-info' in rev.properties)
887
def test_commit_disabled_messages(self):
888
tree = self.make_branch_and_tree('tree')
889
rev_id1 = tree.commit('one')
891
self.build_tree(['tree/a', 'tree/b'])
892
tree.add(['a', 'b'], ['a-id', 'b-id'])
894
dlg = commit.CommitDialog(tree)
895
self.assertFalse(dlg._file_message_expander.get_property('visible'))
896
self.assertEqual('Commit Message',
897
dlg._global_message_label.get_text())
899
tree.branch.get_config().set_user_option('per_file_commits', 'true')
900
dlg = commit.CommitDialog(tree)
901
self.assertTrue(dlg._file_message_expander.get_property('visible'))
902
self.assertEqual('Global Commit Message',
903
dlg._global_message_label.get_text())
905
tree.branch.get_config().set_user_option('per_file_commits', 'on')
906
dlg = commit.CommitDialog(tree)
907
self.assertTrue(dlg._file_message_expander.get_property('visible'))
908
self.assertEqual('Global Commit Message',
909
dlg._global_message_label.get_text())
911
tree.branch.get_config().set_user_option('per_file_commits', 'y')
912
dlg = commit.CommitDialog(tree)
913
self.assertTrue(dlg._file_message_expander.get_property('visible'))
914
self.assertEqual('Global Commit Message',
915
dlg._global_message_label.get_text())
917
tree.branch.get_config().set_user_option('per_file_commits', 'n')
918
dlg = commit.CommitDialog(tree)
919
self.assertFalse(dlg._file_message_expander.get_property('visible'))
920
self.assertEqual('Commit Message',
921
dlg._global_message_label.get_text())
923
def test_commit_specific_files_with_messages(self):
924
tree = self.make_branch_and_tree('tree')
925
tree.branch.get_config().set_user_option('per_file_commits', 'true')
926
rev_id1 = tree.commit('one')
927
self.build_tree(['tree/a', 'tree/b'])
928
tree.add(['a', 'b'], ['a-id', 'b-id'])
930
dlg = commit.CommitDialog(tree)
931
dlg._commit_selected_radio.set_active(True) # enable partial
932
dlg._treeview_files.set_cursor((1,))
933
dlg._set_file_commit_message('Message for A\n')
934
dlg._treeview_files.set_cursor((2,))
935
dlg._set_file_commit_message('Message for B\n')
936
dlg._toggle_commit(None, 2, dlg._files_store) # unset 'b'
937
dlg._set_global_commit_message('Commit just "a"')
941
rev_id2 = dlg.committed_revision_id
942
self.assertEqual(rev_id2, tree.last_revision())
943
rev = tree.branch.repository.get_revision(rev_id2)
944
self.assertEqual('Commit just "a"', rev.message)
945
file_info = rev.properties['file-info']
946
self.assertEqual('ld7:file_id4:a-id'
947
'7:message14:Message for A\n'
950
self.assertEqual([{'path':'a', 'file_id':'a-id',
951
'message':'Message for A\n'},
952
], bencode.bdecode(file_info))
954
def test_commit_messages_after_merge(self):
955
tree = self.make_branch_and_tree('tree')
956
tree.branch.get_config().set_user_option('per_file_commits', 'true')
957
rev_id1 = tree.commit('one')
958
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
959
self.build_tree(['tree2/a', 'tree2/b'])
960
tree2.add(['a', 'b'], ['a-id', 'b-id'])
961
rev_id2 = tree2.commit('two')
963
tree.merge_from_branch(tree2.branch)
965
dlg = commit.CommitDialog(tree)
966
dlg._treeview_files.set_cursor((1,)) # 'a'
967
dlg._set_file_commit_message('Message for A\n')
969
dlg._set_global_commit_message('Merging from "tree2"\n')
973
rev_id3 = dlg.committed_revision_id
974
self.assertEqual(rev_id3, tree.last_revision())
975
rev = tree.branch.repository.get_revision(rev_id3)
976
self.assertEqual('Merging from "tree2"\n', rev.message)
977
self.assertEqual([rev_id1, rev_id2], rev.parent_ids)
978
file_info = rev.properties['file-info']
979
self.assertEqual('ld7:file_id4:a-id'
980
'7:message14:Message for A\n'
983
self.assertEqual([{'path':'a', 'file_id':'a-id',
984
'message':'Message for A\n'},
985
], bencode.bdecode(file_info))
987
def test_commit_unicode_messages(self):
988
self.requireFeature(tests.UnicodeFilenameFeature)
990
tree = self.make_branch_and_tree('tree')
991
tree.branch.get_config().set_user_option('per_file_commits', 'true')
992
self.build_tree(['tree/a', u'tree/\u03a9'])
993
tree.add(['a', u'\u03a9'], ['a-id', 'omega-id'])
995
dlg = commit.CommitDialog(tree)
996
dlg._treeview_files.set_cursor((1,)) # 'a'
997
dlg._set_file_commit_message(u'Test \xfan\xecc\xf6de\n')
998
dlg._treeview_files.set_cursor((2,)) # omega
999
dlg._set_file_commit_message(u'\u03a9 is the end of all things.\n')
1000
dlg._set_global_commit_message(u'\u03a9 and \xfan\xecc\xf6de\n')
1002
self.assertEqual(([u'a', u'\u03a9'],
1003
[{'path':'a', 'file_id':'a-id',
1004
'message':'Test \xc3\xban\xc3\xacc\xc3\xb6de\n'},
1005
{'path':'\xce\xa9', 'file_id':'omega-id',
1006
'message':'\xce\xa9 is the end of all things.\n'},
1007
]), dlg._get_specific_files())
1011
rev = tree.branch.repository.get_revision(dlg.committed_revision_id)
1012
file_info = rev.properties['file-info'].encode('UTF-8')
1013
value = ('ld7:file_id4:a-id'
1014
'7:message16:Test \xc3\xban\xc3\xacc\xc3\xb6de\n'
1017
'd7:file_id8:omega-id'
1018
'7:message29:\xce\xa9 is the end of all things.\n'
1022
self.assertEqual(value, file_info)
1023
file_info_decoded = bencode.bdecode(file_info)
1024
for d in file_info_decoded:
1025
d['path'] = d['path'].decode('UTF-8')
1026
d['message'] = d['message'].decode('UTF-8')
1028
self.assertEqual([{'path':u'a', 'file_id':'a-id',
1029
'message':u'Test \xfan\xecc\xf6de\n'},
1030
{'path':u'\u03a9', 'file_id':'omega-id',
1031
'message':u'\u03a9 is the end of all things.\n'},
1032
], file_info_decoded)