Show More
@@ -0,0 +1,150 b'' | |||||
|
1 | $ cat << EOF >> $HGRCPATH | |||
|
2 | > [extensions] | |||
|
3 | > rebase= | |||
|
4 | > EOF | |||
|
5 | ||||
|
6 | ========================================== | |||
|
7 | Test history-editing-backup config option | | |||
|
8 | ========================================== | |||
|
9 | Test with Pre-obsmarker rebase: | |||
|
10 | 1) When config option is not set: | |||
|
11 | $ hg init repo1 | |||
|
12 | $ cd repo1 | |||
|
13 | $ echo a>a | |||
|
14 | $ hg ci -qAma | |||
|
15 | $ echo b>b | |||
|
16 | $ hg ci -qAmb | |||
|
17 | $ echo c>c | |||
|
18 | $ hg ci -qAmc | |||
|
19 | $ hg up 0 -q | |||
|
20 | $ echo d>d | |||
|
21 | $ hg ci -qAmd | |||
|
22 | $ echo e>e | |||
|
23 | $ hg ci -qAme | |||
|
24 | $ hg log -GT "{rev}: {firstline(desc)}\n" | |||
|
25 | @ 4: e | |||
|
26 | | | |||
|
27 | o 3: d | |||
|
28 | | | |||
|
29 | | o 2: c | |||
|
30 | | | | |||
|
31 | | o 1: b | |||
|
32 | |/ | |||
|
33 | o 0: a | |||
|
34 | ||||
|
35 | $ hg rebase -s 1 -d . | |||
|
36 | rebasing 1:d2ae7f538514 "b" | |||
|
37 | rebasing 2:177f92b77385 "c" | |||
|
38 | saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/d2ae7f538514-c7ed7a78-rebase.hg | |||
|
39 | $ hg log -GT "{rev}: {firstline(desc)}\n" | |||
|
40 | o 4: c | |||
|
41 | | | |||
|
42 | o 3: b | |||
|
43 | | | |||
|
44 | @ 2: e | |||
|
45 | | | |||
|
46 | o 1: d | |||
|
47 | | | |||
|
48 | o 0: a | |||
|
49 | ||||
|
50 | ||||
|
51 | 2) When config option is set: | |||
|
52 | $ cat << EOF >> $HGRCPATH | |||
|
53 | > [ui] | |||
|
54 | > history-editing-backup = False | |||
|
55 | > EOF | |||
|
56 | ||||
|
57 | $ echo f>f | |||
|
58 | $ hg ci -Aqmf | |||
|
59 | $ echo g>g | |||
|
60 | $ hg ci -Aqmg | |||
|
61 | $ hg log -GT "{rev}: {firstline(desc)}\n" | |||
|
62 | @ 6: g | |||
|
63 | | | |||
|
64 | o 5: f | |||
|
65 | | | |||
|
66 | | o 4: c | |||
|
67 | | | | |||
|
68 | | o 3: b | |||
|
69 | |/ | |||
|
70 | o 2: e | |||
|
71 | | | |||
|
72 | o 1: d | |||
|
73 | | | |||
|
74 | o 0: a | |||
|
75 | ||||
|
76 | $ hg rebase -s 3 -d . | |||
|
77 | rebasing 3:05bff2a95b12 "b" | |||
|
78 | rebasing 4:1762bde4404d "c" | |||
|
79 | ||||
|
80 | $ hg log -GT "{rev}: {firstline(desc)}\n" | |||
|
81 | o 6: c | |||
|
82 | | | |||
|
83 | o 5: b | |||
|
84 | | | |||
|
85 | @ 4: g | |||
|
86 | | | |||
|
87 | o 3: f | |||
|
88 | | | |||
|
89 | o 2: e | |||
|
90 | | | |||
|
91 | o 1: d | |||
|
92 | | | |||
|
93 | o 0: a | |||
|
94 | ||||
|
95 | Test when rebased revisions are stripped during abort: | |||
|
96 | ====================================================== | |||
|
97 | ||||
|
98 | $ echo conflict > c | |||
|
99 | $ hg ci -Am "conflict with c" | |||
|
100 | adding c | |||
|
101 | created new head | |||
|
102 | $ hg log -GT "{rev}: {firstline(desc)}\n" | |||
|
103 | @ 7: conflict with c | |||
|
104 | | | |||
|
105 | | o 6: c | |||
|
106 | | | | |||
|
107 | | o 5: b | |||
|
108 | |/ | |||
|
109 | o 4: g | |||
|
110 | | | |||
|
111 | o 3: f | |||
|
112 | | | |||
|
113 | o 2: e | |||
|
114 | | | |||
|
115 | o 1: d | |||
|
116 | | | |||
|
117 | o 0: a | |||
|
118 | ||||
|
119 | When history-editing-backup = True: | |||
|
120 | $ cat << EOF >> $HGRCPATH | |||
|
121 | > [ui] | |||
|
122 | > history-editing-backup = True | |||
|
123 | > EOF | |||
|
124 | $ hg rebase -s 5 -d . | |||
|
125 | rebasing 5:1f8148a544ee "b" | |||
|
126 | rebasing 6:f8bc7d28e573 "c" | |||
|
127 | merging c | |||
|
128 | warning: conflicts while merging c! (edit, then use 'hg resolve --mark') | |||
|
129 | unresolved conflicts (see hg resolve, then hg rebase --continue) | |||
|
130 | [1] | |||
|
131 | $ hg rebase --abort | |||
|
132 | saved backup bundle to $TESTTMP/repo1/.hg/strip-backup/818c1a43c916-2b644d96-backup.hg | |||
|
133 | rebase aborted | |||
|
134 | ||||
|
135 | When history-editing-backup = False: | |||
|
136 | $ cat << EOF >> $HGRCPATH | |||
|
137 | > [ui] | |||
|
138 | > history-editing-backup = False | |||
|
139 | > EOF | |||
|
140 | $ hg rebase -s 5 -d . | |||
|
141 | rebasing 5:1f8148a544ee "b" | |||
|
142 | rebasing 6:f8bc7d28e573 "c" | |||
|
143 | merging c | |||
|
144 | warning: conflicts while merging c! (edit, then use 'hg resolve --mark') | |||
|
145 | unresolved conflicts (see hg resolve, then hg rebase --continue) | |||
|
146 | [1] | |||
|
147 | $ hg rebase --abort | |||
|
148 | rebase aborted | |||
|
149 | $ cd .. | |||
|
150 |
@@ -585,7 +585,11 b' class rebaseruntime(object):' | |||||
585 | # case and realize that the commit was in progress. |
|
585 | # case and realize that the commit was in progress. | |
586 | self.storestatus() |
|
586 | self.storestatus() | |
587 |
|
587 | |||
588 | def _finishrebase(self): |
|
588 | def _finishrebase(self, backup=True): | |
|
589 | """ | |||
|
590 | backup: if False, no backup will be stored when stripping rebased | |||
|
591 | revisions | |||
|
592 | """ | |||
589 | repo, ui, opts = self.repo, self.ui, self.opts |
|
593 | repo, ui, opts = self.repo, self.ui, self.opts | |
590 | fm = ui.formatter('rebase', opts) |
|
594 | fm = ui.formatter('rebase', opts) | |
591 | fm.startitem() |
|
595 | fm.startitem() | |
@@ -632,7 +636,7 b' class rebaseruntime(object):' | |||||
632 | if self.collapsef and not self.keepf: |
|
636 | if self.collapsef and not self.keepf: | |
633 | collapsedas = newnode |
|
637 | collapsedas = newnode | |
634 | clearrebased(ui, repo, self.destmap, self.state, self.skipped, |
|
638 | clearrebased(ui, repo, self.destmap, self.state, self.skipped, | |
635 | collapsedas, self.keepf, fm=fm) |
|
639 | collapsedas, self.keepf, fm=fm, backup=backup) | |
636 |
|
640 | |||
637 | clearstatus(repo) |
|
641 | clearstatus(repo) | |
638 | clearcollapsemsg(repo) |
|
642 | clearcollapsemsg(repo) | |
@@ -829,6 +833,8 b' def rebase(ui, repo, **opts):' | |||||
829 | userrevs = list(repo.revs(opts.get('auto_orphans'))) |
|
833 | userrevs = list(repo.revs(opts.get('auto_orphans'))) | |
830 | opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)] |
|
834 | opts['rev'] = [revsetlang.formatspec('%ld and orphan()', userrevs)] | |
831 | opts['dest'] = '_destautoorphanrebase(SRC)' |
|
835 | opts['dest'] = '_destautoorphanrebase(SRC)' | |
|
836 | backup = ui.configbool('ui', 'history-editing-backup') | |||
|
837 | opts['backup'] = backup | |||
832 |
|
838 | |||
833 | if dryrun: |
|
839 | if dryrun: | |
834 | return _dryrunrebase(ui, repo, opts) |
|
840 | return _dryrunrebase(ui, repo, opts) | |
@@ -850,6 +856,7 b' def rebase(ui, repo, **opts):' | |||||
850 | def _dryrunrebase(ui, repo, opts): |
|
856 | def _dryrunrebase(ui, repo, opts): | |
851 | rbsrt = rebaseruntime(repo, ui, inmemory=True, opts=opts) |
|
857 | rbsrt = rebaseruntime(repo, ui, inmemory=True, opts=opts) | |
852 | confirm = opts.get('confirm') |
|
858 | confirm = opts.get('confirm') | |
|
859 | backup = opts.get('backup') | |||
853 | if confirm: |
|
860 | if confirm: | |
854 | ui.status(_('starting in-memory rebase\n')) |
|
861 | ui.status(_('starting in-memory rebase\n')) | |
855 | else: |
|
862 | else: | |
@@ -871,7 +878,7 b' def _dryrunrebase(ui, repo, opts):' | |||||
871 | if not ui.promptchoice(_(b'apply changes (yn)?' |
|
878 | if not ui.promptchoice(_(b'apply changes (yn)?' | |
872 | b'$$ &Yes $$ &No')): |
|
879 | b'$$ &Yes $$ &No')): | |
873 | # finish unfinished rebase |
|
880 | # finish unfinished rebase | |
874 | rbsrt._finishrebase() |
|
881 | rbsrt._finishrebase(backup=backup) | |
875 | else: |
|
882 | else: | |
876 | rbsrt._prepareabortorcontinue(isabort=True, backup=False, |
|
883 | rbsrt._prepareabortorcontinue(isabort=True, backup=False, | |
877 | suppwarns=True) |
|
884 | suppwarns=True) | |
@@ -902,6 +909,7 b' def _origrebase(ui, repo, opts, rbsrt, i' | |||||
902 | destspace = opts.get('_destspace') |
|
909 | destspace = opts.get('_destspace') | |
903 | contf = opts.get('continue') |
|
910 | contf = opts.get('continue') | |
904 | abortf = opts.get('abort') |
|
911 | abortf = opts.get('abort') | |
|
912 | backup = opts.get('backup') | |||
905 | if opts.get('interactive'): |
|
913 | if opts.get('interactive'): | |
906 | try: |
|
914 | try: | |
907 | if extensions.find('histedit'): |
|
915 | if extensions.find('histedit'): | |
@@ -932,7 +940,7 b' def _origrebase(ui, repo, opts, rbsrt, i' | |||||
932 | ms = mergemod.mergestate.read(repo) |
|
940 | ms = mergemod.mergestate.read(repo) | |
933 | mergeutil.checkunresolved(ms) |
|
941 | mergeutil.checkunresolved(ms) | |
934 |
|
942 | |||
935 | retcode = rbsrt._prepareabortorcontinue(abortf) |
|
943 | retcode = rbsrt._prepareabortorcontinue(abortf, backup=backup) | |
936 | if retcode is not None: |
|
944 | if retcode is not None: | |
937 | return retcode |
|
945 | return retcode | |
938 | else: |
|
946 | else: | |
@@ -961,7 +969,7 b' def _origrebase(ui, repo, opts, rbsrt, i' | |||||
961 | with util.acceptintervention(dsguard): |
|
969 | with util.acceptintervention(dsguard): | |
962 | rbsrt._performrebase(tr) |
|
970 | rbsrt._performrebase(tr) | |
963 | if not leaveunfinished: |
|
971 | if not leaveunfinished: | |
964 | rbsrt._finishrebase() |
|
972 | rbsrt._finishrebase(backup=backup) | |
965 |
|
973 | |||
966 | def _definedestmap(ui, repo, inmemory, destf=None, srcf=None, basef=None, |
|
974 | def _definedestmap(ui, repo, inmemory, destf=None, srcf=None, basef=None, | |
967 | revf=None, destspace=None): |
|
975 | revf=None, destspace=None): | |
@@ -1728,7 +1736,7 b' def buildstate(repo, destmap, collapse):' | |||||
1728 | return originalwd, destmap, state |
|
1736 | return originalwd, destmap, state | |
1729 |
|
1737 | |||
1730 | def clearrebased(ui, repo, destmap, state, skipped, collapsedas=None, |
|
1738 | def clearrebased(ui, repo, destmap, state, skipped, collapsedas=None, | |
1731 | keepf=False, fm=None): |
|
1739 | keepf=False, fm=None, backup=True): | |
1732 | """dispose of rebased revision at the end of the rebase |
|
1740 | """dispose of rebased revision at the end of the rebase | |
1733 |
|
1741 | |||
1734 | If `collapsedas` is not None, the rebase was a collapse whose result if the |
|
1742 | If `collapsedas` is not None, the rebase was a collapse whose result if the | |
@@ -1736,6 +1744,9 b' def clearrebased(ui, repo, destmap, stat' | |||||
1736 |
|
1744 | |||
1737 | If `keepf` is not True, the rebase has --keep set and no nodes should be |
|
1745 | If `keepf` is not True, the rebase has --keep set and no nodes should be | |
1738 | removed (but bookmarks still need to be moved). |
|
1746 | removed (but bookmarks still need to be moved). | |
|
1747 | ||||
|
1748 | If `backup` is False, no backup will be stored when stripping rebased | |||
|
1749 | revisions. | |||
1739 | """ |
|
1750 | """ | |
1740 | tonode = repo.changelog.node |
|
1751 | tonode = repo.changelog.node | |
1741 | replacements = {} |
|
1752 | replacements = {} | |
@@ -1751,7 +1762,7 b' def clearrebased(ui, repo, destmap, stat' | |||||
1751 | else: |
|
1762 | else: | |
1752 | succs = (newnode,) |
|
1763 | succs = (newnode,) | |
1753 | replacements[oldnode] = succs |
|
1764 | replacements[oldnode] = succs | |
1754 | scmutil.cleanupnodes(repo, replacements, 'rebase', moves) |
|
1765 | scmutil.cleanupnodes(repo, replacements, 'rebase', moves, backup=backup) | |
1755 | if fm: |
|
1766 | if fm: | |
1756 | hf = fm.hexfunc |
|
1767 | hf = fm.hexfunc | |
1757 | fl = fm.formatlist |
|
1768 | fl = fm.formatlist |
@@ -298,24 +298,24 b' class stripcallback(object):' | |||||
298 | if roots: |
|
298 | if roots: | |
299 | strip(self.ui, self.repo, roots, self.backup, self.topic) |
|
299 | strip(self.ui, self.repo, roots, self.backup, self.topic) | |
300 |
|
300 | |||
301 | def delayedstrip(ui, repo, nodelist, topic=None): |
|
301 | def delayedstrip(ui, repo, nodelist, topic=None, backup=True): | |
302 | """like strip, but works inside transaction and won't strip irreverent revs |
|
302 | """like strip, but works inside transaction and won't strip irreverent revs | |
303 |
|
303 | |||
304 | nodelist must explicitly contain all descendants. Otherwise a warning will |
|
304 | nodelist must explicitly contain all descendants. Otherwise a warning will | |
305 | be printed that some nodes are not stripped. |
|
305 | be printed that some nodes are not stripped. | |
306 |
|
306 | |||
307 |
|
|
307 | Will do a backup if `backup` is True. The last non-None "topic" will be | |
308 | topic name. The default backup topic name is "backup". |
|
308 | used as the backup topic name. The default backup topic name is "backup". | |
309 | """ |
|
309 | """ | |
310 | tr = repo.currenttransaction() |
|
310 | tr = repo.currenttransaction() | |
311 | if not tr: |
|
311 | if not tr: | |
312 | nodes = safestriproots(ui, repo, nodelist) |
|
312 | nodes = safestriproots(ui, repo, nodelist) | |
313 |
return strip(ui, repo, nodes, |
|
313 | return strip(ui, repo, nodes, backup=backup, topic=topic) | |
314 | # transaction postclose callbacks are called in alphabet order. |
|
314 | # transaction postclose callbacks are called in alphabet order. | |
315 | # use '\xff' as prefix so we are likely to be called last. |
|
315 | # use '\xff' as prefix so we are likely to be called last. | |
316 | callback = tr.getpostclose('\xffstrip') |
|
316 | callback = tr.getpostclose('\xffstrip') | |
317 | if callback is None: |
|
317 | if callback is None: | |
318 |
callback = stripcallback(ui, repo, |
|
318 | callback = stripcallback(ui, repo, backup=backup, topic=topic) | |
319 | tr.addpostclose('\xffstrip', callback) |
|
319 | tr.addpostclose('\xffstrip', callback) | |
320 | if topic: |
|
320 | if topic: | |
321 | callback.topic = topic |
|
321 | callback.topic = topic |
@@ -780,7 +780,7 b' class _containsnode(object):' | |||||
780 | return self._revcontains(self._torev(node)) |
|
780 | return self._revcontains(self._torev(node)) | |
781 |
|
781 | |||
782 | def cleanupnodes(repo, replacements, operation, moves=None, metadata=None, |
|
782 | def cleanupnodes(repo, replacements, operation, moves=None, metadata=None, | |
783 | fixphase=False, targetphase=None): |
|
783 | fixphase=False, targetphase=None, backup=True): | |
784 | """do common cleanups when old nodes are replaced by new nodes |
|
784 | """do common cleanups when old nodes are replaced by new nodes | |
785 |
|
785 | |||
786 | That includes writing obsmarkers or stripping nodes, and moving bookmarks. |
|
786 | That includes writing obsmarkers or stripping nodes, and moving bookmarks. | |
@@ -905,7 +905,8 b' def cleanupnodes(repo, replacements, ope' | |||||
905 | from . import repair # avoid import cycle |
|
905 | from . import repair # avoid import cycle | |
906 | tostrip = list(replacements) |
|
906 | tostrip = list(replacements) | |
907 | if tostrip: |
|
907 | if tostrip: | |
908 |
repair.delayedstrip(repo.ui, repo, tostrip, operation |
|
908 | repair.delayedstrip(repo.ui, repo, tostrip, operation, | |
|
909 | backup=backup) | |||
909 |
|
910 | |||
910 | def addremove(repo, matcher, prefix, opts=None): |
|
911 | def addremove(repo, matcher, prefix, opts=None): | |
911 | if opts is None: |
|
912 | if opts is None: |
General Comments 0
You need to be logged in to leave comments.
Login now