-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathe --onto
1161 lines (829 loc) · 66.1 KB
/
e --onto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
GIT-REBASE(1) Git Manual GIT-REBASE(1)
NNAAMMEE
git-rebase - Reapply commits on top of another base tip
SSYYNNOOPPSSIISS
_g_i_t _r_e_b_a_s_e [-i | --interactive] [<options>] [--exec <cmd>]
[--onto <newbase> | --keep-base] [<upstream> [<branch>]]
_g_i_t _r_e_b_a_s_e [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]
--root [<branch>]
_g_i_t _r_e_b_a_s_e (--continue | --skip | --abort | --quit | --edit-todo | --show-current-patch)
DDEESSCCRRIIPPTTIIOONN
If <branch> is specified, _g_i_t _r_e_b_a_s_e will perform an automatic ggiitt sswwiittcchh <<bbrraanncchh>> before doing anything else.
Otherwise it remains on the current branch.
If <upstream> is not specified, the upstream configured in branch.<name>.remote and branch.<name>.merge
options will be used (see ggiitt--ccoonnffiigg(1) for details) and the ----ffoorrkk--ppooiinntt option is assumed. If you are
currently not on any branch or if the current branch does not have a configured upstream, the rebase will
abort.
All changes made by commits in the current branch but that are not in <upstream> are saved to a temporary
area. This is the same set of commits that would be shown by ggiitt lloogg <<uuppssttrreeaamm>>....HHEEAADD; or by ggiitt lloogg
''ffoorrkk__ppooiinntt''....HHEEAADD, if ----ffoorrkk--ppooiinntt is active (see the description on ----ffoorrkk--ppooiinntt below); or by ggiitt lloogg HHEEAADD,
if the ----rroooott option is specified.
The current branch is reset to <upstream>, or <newbase> if the --onto option was supplied. This has the exact
same effect as ggiitt rreesseett ----hhaarrdd <<uuppssttrreeaamm>> (or <newbase>). ORIG_HEAD is set to point at the tip of the branch
before the reset.
The commits that were previously saved into the temporary area are then reapplied to the current branch, one
by one, in order. Note that any commits in HEAD which introduce the same textual changes as a commit in
HEAD..<upstream> are omitted (i.e., a patch already accepted upstream with a different commit message or
timestamp will be skipped).
It is possible that a merge failure will prevent this process from being completely automatic. You will have
to resolve any such merge failure and run ggiitt rreebbaassee ----ccoonnttiinnuuee. Another option is to bypass the commit that
caused the merge failure with ggiitt rreebbaassee ----sskkiipp. To check out the original <branch> and remove the
.git/rebase-apply working files, use the command ggiitt rreebbaassee ----aabboorrtt instead.
Assume the following history exists and the current branch is "topic":
A---B---C topic
/
D---E---F---G master
From this point, the result of either of the following commands:
git rebase master
git rebase master topic
would be:
A'--B'--C' topic
/
D---E---F---G master
NNOOTTEE:: The latter form is just a short-hand of ggiitt cchheecckkoouutt ttooppiicc followed by ggiitt rreebbaassee mmaasstteerr. When rebase
exits ttooppiicc will remain the checked-out branch.
If the upstream branch already contains a change you have made (e.g., because you mailed a patch which was
applied upstream), then that commit will be skipped. For example, running ggiitt rreebbaassee mmaasstteerr on the following
history (in which AA'' and AA introduce the same set of changes, but have different committer information):
A---B---C topic
/
D---E---A'---F master
will result in:
B'---C' topic
/
D---E---A'---F master
Here is how you would transplant a topic branch based on one branch to another, to pretend that you forked the
topic branch from the latter branch, using rreebbaassee ----oonnttoo.
First let’s assume your _t_o_p_i_c is based on branch _n_e_x_t. For example, a feature developed in _t_o_p_i_c depends on
some functionality which is found in _n_e_x_t.
o---o---o---o---o master
\
o---o---o---o---o next
\
o---o---o topic
We want to make _t_o_p_i_c forked from branch _m_a_s_t_e_r; for example, because the functionality on which _t_o_p_i_c depends
was merged into the more stable _m_a_s_t_e_r branch. We want our tree to look like this:
o---o---o---o---o master
| \
| o'--o'--o' topic
\
o---o---o---o---o next
We can get this using the following command:
git rebase --onto master next topic
Another example of --onto option is to rebase part of a branch. If we have the following situation:
H---I---J topicB
/
E---F---G topicA
/
A---B---C---D master
then the command
git rebase --onto master topicA topicB
would result in:
H'--I'--J' topicB
/
| E---F---G topicA
|/
A---B---C---D master
This is useful when topicB does not depend on topicA.
A range of commits could also be removed with rebase. If we have the following situation:
E---F---G---H---I---J topicA
then the command
git rebase --onto topicA~5 topicA~3 topicA
would result in the removal of commits F and G:
E---H'---I'---J' topicA
This is useful if F and G were flawed in some way, or should not be part of topicA. Note that the argument to
--onto and the <upstream> parameter can be any valid commit-ish.
In case of conflict, _g_i_t _r_e_b_a_s_e will stop at the first problematic commit and leave conflict markers in the
tree. You can use _g_i_t _d_i_f_f to locate the markers (<<<<<<) and make edits to resolve the conflict. For each
file you edit, you need to tell Git that the conflict has been resolved, typically this would be done with
git add <filename>
After resolving the conflict manually and updating the index with the desired resolution, you can continue the
rebasing process with
git rebase --continue
Alternatively, you can undo the _g_i_t _r_e_b_a_s_e with
git rebase --abort
OOPPTTIIOONNSS
--onto <newbase>
Starting point at which to create the new commits. If the --onto option is not specified, the starting
point is <upstream>. May be any valid commit, and not just an existing branch name.
As a special case, you may use "A...B" as a shortcut for the merge base of A and B if there is exactly one
merge base. You can leave out at most one of A and B, in which case it defaults to HEAD.
--keep-base
Set the starting point at which to create the new commits to the merge base of <upstream> <branch>.
Running _g_i_t _r_e_b_a_s_e _-_-_k_e_e_p_-_b_a_s_e _<_u_p_s_t_r_e_a_m_> _<_b_r_a_n_c_h_> is equivalent to running _g_i_t _r_e_b_a_s_e _-_-_o_n_t_o
_<_u_p_s_t_r_e_a_m_>_._._. _<_u_p_s_t_r_e_a_m_>.
This option is useful in the case where one is developing a feature on top of an upstream branch. While
the feature is being worked on, the upstream branch may advance and it may not be the best idea to keep
rebasing on top of the upstream but to keep the base commit as-is.
Although both this option and --fork-point find the merge base between <upstream> and <branch>, this
option uses the merge base as the _s_t_a_r_t_i_n_g _p_o_i_n_t on which new commits will be created, whereas
--fork-point uses the merge base to determine the _s_e_t _o_f _c_o_m_m_i_t_s which will be rebased.
See also INCOMPATIBLE OPTIONS below.
<upstream>
Upstream branch to compare against. May be any valid commit, not just an existing branch name. Defaults to
the configured upstream for the current branch.
<branch>
Working branch; defaults to HEAD.
--continue
Restart the rebasing process after having resolved a merge conflict.
--abort
Abort the rebase operation and reset HEAD to the original branch. If <branch> was provided when the rebase
operation was started, then HEAD will be reset to <branch>. Otherwise HEAD will be reset to where it was
when the rebase operation was started.
--quit
Abort the rebase operation but HEAD is not reset back to the original branch. The index and working tree
are also left unchanged as a result. If a temporary stash entry was created using --autostash, it will be
saved to the stash list.
--apply
Use applying strategies to rebase (calling ggiitt--aamm internally). This option may become a no-op in the
future once the merge backend handles everything the apply one does.
See also INCOMPATIBLE OPTIONS below.
--empty={drop,keep,ask}
How to handle commits that are not empty to start and are not clean cherry-picks of any upstream commit,
but which become empty after rebasing (because they contain a subset of already upstream changes). With
drop (the default), commits that become empty are dropped. With keep, such commits are kept. With ask
(implied by --interactive), the rebase will halt when an empty commit is applied allowing you to choose
whether to drop it, edit files more, or just commit the empty changes. Other options, like --exec, will
use the default of drop unless -i/--interactive is explicitly specified.
Note that commits which start empty are kept (unless --no-keep-empty is specified), and commits which are
clean cherry-picks (as determined by ggiitt lloogg ----cchheerrrryy--mmaarrkk ......) are detected and dropped as a preliminary
step (unless --reapply-cherry-picks is passed).
See also INCOMPATIBLE OPTIONS below.
--no-keep-empty, --keep-empty
Do not keep commits that start empty before the rebase (i.e. that do not change anything from its parent)
in the result. The default is to keep commits which start empty, since creating such commits requires
passing the --allow-empty override flag to ggiitt ccoommmmiitt, signifying that a user is very intentionally
creating such a commit and thus wants to keep it.
Usage of this flag will probably be rare, since you can get rid of commits that start empty by just firing
up an interactive rebase and removing the lines corresponding to the commits you don’t want. This flag
exists as a convenient shortcut, such as for cases where external tools generate many empty commits and
you want them all removed.
For commits which do not start empty but become empty after rebasing, see the --empty flag.
See also INCOMPATIBLE OPTIONS below.
--reapply-cherry-picks, --no-reapply-cherry-picks
Reapply all clean cherry-picks of any upstream commit instead of preemptively dropping them. (If these
commits then become empty after rebasing, because they contain a subset of already upstream changes, the
behavior towards them is controlled by the ----eemmppttyy flag.)
By default (or if ----nnoo--rreeaappppllyy--cchheerrrryy--ppiicckkss is given), these commits will be automatically dropped.
Because this necessitates reading all upstream commits, this can be expensive in repos with a large number
of upstream commits that need to be read.
----rreeaappppllyy--cchheerrrryy--ppiicckkss allows rebase to forgo reading all upstream commits, potentially improving
performance.
See also INCOMPATIBLE OPTIONS below.
--allow-empty-message
No-op. Rebasing commits with an empty message used to fail and this option would override that behavior,
allowing commits with empty messages to be rebased. Now commits with an empty message do not cause
rebasing to halt.
See also INCOMPATIBLE OPTIONS below.
--skip
Restart the rebasing process by skipping the current patch.
--edit-todo
Edit the todo list during an interactive rebase.
--show-current-patch
Show the current patch in an interactive rebase or when rebase is stopped because of conflicts. This is
the equivalent of ggiitt sshhooww RREEBBAASSEE__HHEEAADD.
-m, --merge
Use merging strategies to rebase. When the recursive (default) merge strategy is used, this allows rebase
to be aware of renames on the upstream side. This is the default.
Note that a rebase merge works by replaying each commit from the working branch on top of the <upstream>
branch. Because of this, when a merge conflict happens, the side reported as _o_u_r_s is the so-far rebased
series, starting with <upstream>, and _t_h_e_i_r_s is the working branch. In other words, the sides are swapped.
See also INCOMPATIBLE OPTIONS below.
-s <strategy>, --strategy=<strategy>
Use the given merge strategy. If there is no --ss option _g_i_t _m_e_r_g_e_-_r_e_c_u_r_s_i_v_e is used instead. This implies
--merge.
Because _g_i_t _r_e_b_a_s_e replays each commit from the working branch on top of the <upstream> branch using the
given strategy, using the _o_u_r_s strategy simply empties all patches from the <branch>, which makes little
sense.
See also INCOMPATIBLE OPTIONS below.
-X <strategy-option>, --strategy-option=<strategy-option>
Pass the <strategy-option> through to the merge strategy. This implies ----mmeerrggee and, if no strategy has
been specified, --ss rreeccuurrssiivvee. Note the reversal of _o_u_r_s and _t_h_e_i_r_s as noted above for the --mm option.
See also INCOMPATIBLE OPTIONS below.
--rerere-autoupdate, --no-rerere-autoupdate
Allow the rerere mechanism to update the index with the result of auto-conflict resolution if possible.
-S[<keyid>], --gpg-sign[=<keyid>], --no-gpg-sign
GPG-sign commits. The kkeeyyiidd argument is optional and defaults to the committer identity; if specified, it
must be stuck to the option without a space. ----nnoo--ggppgg--ssiiggnn is useful to countermand both ccoommmmiitt..ggppggSSiiggnn
configuration variable, and earlier ----ggppgg--ssiiggnn.
-q, --quiet
Be quiet. Implies --no-stat.
-v, --verbose
Be verbose. Implies --stat.
--stat
Show a diffstat of what changed upstream since the last rebase. The diffstat is also controlled by the
configuration option rebase.stat.
-n, --no-stat
Do not show a diffstat as part of the rebase process.
--no-verify
This option bypasses the pre-rebase hook. See also ggiitthhooookkss(5).
--verify
Allows the pre-rebase hook to run, which is the default. This option can be used to override --no-verify.
See also ggiitthhooookkss(5).
-C<n>
Ensure at least <n> lines of surrounding context match before and after each change. When fewer lines of
surrounding context exist they all must match. By default no context is ever ignored. Implies --apply.
See also INCOMPATIBLE OPTIONS below.
--no-ff, --force-rebase, -f
Individually replay all rebased commits instead of fast-forwarding over the unchanged ones. This ensures
that the entire history of the rebased branch is composed of new commits.
You may find this helpful after reverting a topic branch merge, as this option recreates the topic branch
with fresh commits so it can be remerged successfully without needing to "revert the reversion" (see the
rreevveerrtt--aa--ffaauullttyy--mmeerrggee HHooww--TToo[1] for details).
--fork-point, --no-fork-point
Use reflog to find a better common ancestor between <upstream> and <branch> when calculating which commits
have been introduced by <branch>.
When --fork-point is active, _f_o_r_k___p_o_i_n_t will be used instead of <upstream> to calculate the set of commits
to rebase, where _f_o_r_k___p_o_i_n_t is the result of ggiitt mmeerrggee--bbaassee ----ffoorrkk--ppooiinntt <<uuppssttrreeaamm>> <<bbrraanncchh>> command (see
ggiitt--mmeerrggee--bbaassee(1)). If _f_o_r_k___p_o_i_n_t ends up being empty, the <upstream> will be used as a fallback.
If <upstream> is given on the command line, then the default is ----nnoo--ffoorrkk--ppooiinntt, otherwise the default is
----ffoorrkk--ppooiinntt.
If your branch was based on <upstream> but <upstream> was rewound and your branch contains commits which
were dropped, this option can be used with ----kkeeeepp--bbaassee in order to drop those commits from your branch.
See also INCOMPATIBLE OPTIONS below.
--ignore-whitespace
Ignore whitespace differences when trying to reconcile differences. Currently, each backend implements an
approximation of this behavior:
apply backend: When applying a patch, ignore changes in whitespace in context lines. Unfortunately, this
means that if the "old" lines being replaced by the patch differ only in whitespace from the existing
file, you will get a merge conflict instead of a successful patch application.
merge backend: Treat lines with only whitespace changes as unchanged when merging. Unfortunately, this
means that any patch hunks that were intended to modify whitespace and nothing else will be dropped, even
if the other side had no changes that conflicted.
--whitespace=<option>
This flag is passed to the _g_i_t _a_p_p_l_y program (see ggiitt--aappppllyy(1)) that applies the patch. Implies --apply.
See also INCOMPATIBLE OPTIONS below.
--committer-date-is-author-date
Instead of using the current time as the committer date, use the author date of the commit being rebased
as the committer date. This option implies ----ffoorrccee--rreebbaassee.
--ignore-date, --reset-author-date
Instead of using the author date of the original commit, use the current time as the author date of the
rebased commit. This option implies ----ffoorrccee--rreebbaassee.
See also INCOMPATIBLE OPTIONS below.
--signoff
Add a SSiiggnneedd--ooffff--bbyy trailer to all the rebased commits. Note that if ----iinntteerraaccttiivvee is given then only
commits marked to be picked, edited or reworded will have the trailer added.
See also INCOMPATIBLE OPTIONS below.
-i, --interactive
Make a list of the commits which are about to be rebased. Let the user edit that list before rebasing.
This mode can also be used to split commits (see SPLITTING COMMITS below).
The commit list format can be changed by setting the configuration option rebase.instructionFormat. A
customized instruction format will automatically have the long commit hash prepended to the format.
See also INCOMPATIBLE OPTIONS below.
-r, --rebase-merges[=(rebase-cousins|no-rebase-cousins)]
By default, a rebase will simply drop merge commits from the todo list, and put the rebased commits into a
single, linear branch. With ----rreebbaassee--mmeerrggeess, the rebase will instead try to preserve the branching
structure within the commits that are to be rebased, by recreating the merge commits. Any resolved merge
conflicts or manual amendments in these merge commits will have to be resolved/re-applied manually.
By default, or when nnoo--rreebbaassee--ccoouussiinnss was specified, commits which do not have <<uuppssttrreeaamm>> as direct
ancestor will keep their original branch point, i.e. commits that would be excluded by ggiitt--lloogg(1)'s
----aanncceessttrryy--ppaatthh option will keep their original ancestry by default. If the rreebbaassee--ccoouussiinnss mode is turned
on, such commits are instead rebased onto <<uuppssttrreeaamm>> (or <<oonnttoo>>, if specified).
The ----rreebbaassee--mmeerrggeess mode is similar in spirit to the deprecated ----pprreesseerrvvee--mmeerrggeess but works with
interactive rebases, where commits can be reordered, inserted and dropped at will.
It is currently only possible to recreate the merge commits using the rreeccuurrssiivvee merge strategy; Different
merge strategies can be used only via explicit eexxeecc ggiitt mmeerrggee --ss <<ssttrraatteeggyy>> [[......]] commands.
See also REBASING MERGES and INCOMPATIBLE OPTIONS below.
-p, --preserve-merges
[DEPRECATED: use ----rreebbaassee--mmeerrggeess instead] Recreate merge commits instead of flattening the history by
replaying commits a merge commit introduces. Merge conflict resolutions or manual amendments to merge
commits are not preserved.
This uses the ----iinntteerraaccttiivvee machinery internally, but combining it with the ----iinntteerraaccttiivvee option
explicitly is generally not a good idea unless you know what you are doing (see BUGS below).
See also INCOMPATIBLE OPTIONS below.
-x <cmd>, --exec <cmd>
Append "exec <cmd>" after each line creating a commit in the final history. <cmd> will be interpreted as
one or more shell commands. Any command that fails will interrupt the rebase, with exit code 1.
You may execute several commands by either using one instance of ----eexxeecc with several commands:
git rebase -i --exec "cmd1 && cmd2 && ..."
or by giving more than one ----eexxeecc:
git rebase -i --exec "cmd1" --exec "cmd2" --exec ...
If ----aauuttoossqquuaasshh is used, "exec" lines will not be appended for the intermediate commits, and will only
appear at the end of each squash/fixup series.
This uses the ----iinntteerraaccttiivvee machinery internally, but it can be run without an explicit ----iinntteerraaccttiivvee.
See also INCOMPATIBLE OPTIONS below.
--root
Rebase all commits reachable from <branch>, instead of limiting them with an <upstream>. This allows you
to rebase the root commit(s) on a branch. When used with --onto, it will skip changes already contained in
<newbase> (instead of <upstream>) whereas without --onto it will operate on every change. When used
together with both --onto and --preserve-merges, _a_l_l root commits will be rewritten to have <newbase> as
parent instead.
See also INCOMPATIBLE OPTIONS below.
--autosquash, --no-autosquash
When the commit log message begins with "squash! ..." or "fixup! ..." or "amend! ...", and there is
already a commit in the todo list that matches the same ......, automatically modify the todo list of rreebbaassee
--ii, so that the commit marked for squashing comes right after the commit to be modified, and change the
action of the moved commit from ppiicckk to ssqquuaasshh or ffiixxuupp or ffiixxuupp --CC respectively. A commit matches the ......
if the commit subject matches, or if the ...... refers to the commit’s hash. As a fall-back, partial matches
of the commit subject work, too. The recommended way to create fixup/amend/squash commits is by using the
----ffiixxuupp, ----ffiixxuupp==aammeenndd:: or ----ffiixxuupp==rreewwoorrdd:: and ----ssqquuaasshh options respectively of ggiitt--ccoommmmiitt(1).
If the ----aauuttoossqquuaasshh option is enabled by default using the configuration variable rreebbaassee..aauuttooSSqquuaasshh, this
option can be used to override and disable this setting.
See also INCOMPATIBLE OPTIONS below.
--autostash, --no-autostash
Automatically create a temporary stash entry before the operation begins, and apply it after the operation
ends. This means that you can run rebase on a dirty worktree. However, use with care: the final stash
application after a successful rebase might result in non-trivial conflicts.
--reschedule-failed-exec, --no-reschedule-failed-exec
Automatically reschedule eexxeecc commands that failed. This only makes sense in interactive mode (or when an
----eexxeecc option was provided).
Even though this option applies once a rebase is started, it’s set for the whole rebase at the start based
on either the rreebbaassee..rreesscchheedduulleeFFaaiilleeddEExxeecc configuration (see ggiitt--ccoonnffiigg(1) or "CONFIGURATION" below) or
whether this option is provided. Otherwise an explicit ----nnoo--rreesscchheedduullee--ffaaiilleedd--eexxeecc at the start would be
overridden by the presence of rreebbaassee..rreesscchheedduulleeFFaaiilleeddEExxeecc==ttrruuee configuration.
IINNCCOOMMPPAATTIIBBLLEE OOPPTTIIOONNSS
The following options:
• --apply
• --whitespace
• -C
are incompatible with the following options:
• --merge
• --strategy
• --strategy-option
• --allow-empty-message
• --[no-]autosquash
• --rebase-merges
• --preserve-merges
• --interactive
• --exec
• --no-keep-empty
• --empty=
• --reapply-cherry-picks
• --edit-todo
• --root when used in combination with --onto
In addition, the following pairs of options are incompatible:
• --preserve-merges and --interactive
• --preserve-merges and --signoff
• --preserve-merges and --rebase-merges
• --preserve-merges and --empty=
• --preserve-merges and --ignore-whitespace
• --preserve-merges and --committer-date-is-author-date
• --preserve-merges and --ignore-date
• --keep-base and --onto
• --keep-base and --root
• --fork-point and --root
BBEEHHAAVVIIOORRAALL DDIIFFFFEERREENNCCEESS
git rebase has two primary backends: apply and merge. (The apply backend used to be known as the _a_m backend,
but the name led to confusion as it looks like a verb instead of a noun. Also, the merge backend used to be
known as the interactive backend, but it is now used for non-interactive cases as well. Both were renamed
based on lower-level functionality that underpinned each.) There are some subtle differences in how these two
backends behave:
EEmmppttyy ccoommmmiittss
The apply backend unfortunately drops intentionally empty commits, i.e. commits that started empty, though
these are rare in practice. It also drops commits that become empty and has no option for controlling this
behavior.
The merge backend keeps intentionally empty commits by default (though with -i they are marked as empty in the
todo list editor, or they can be dropped automatically with --no-keep-empty).
Similar to the apply backend, by default the merge backend drops commits that become empty unless
-i/--interactive is specified (in which case it stops and asks the user what to do). The merge backend also
has an --empty={drop,keep,ask} option for changing the behavior of handling commits that become empty.
DDiirreeccttoorryy rreennaammee ddeetteeccttiioonn
Due to the lack of accurate tree information (arising from constructing fake ancestors with the limited
information available in patches), directory rename detection is disabled in the apply backend. Disabled
directory rename detection means that if one side of history renames a directory and the other adds new files
to the old directory, then the new files will be left behind in the old directory without any warning at the
time of rebasing that you may want to move these files into the new directory.
Directory rename detection works with the merge backend to provide you warnings in such cases.
CCoonntteexxtt
The apply backend works by creating a sequence of patches (by calling ffoorrmmaatt--ppaattcchh internally), and then
applying the patches in sequence (calling aamm internally). Patches are composed of multiple hunks, each with
line numbers, a context region, and the actual changes. The line numbers have to be taken with some fuzz,
since the other side will likely have inserted or deleted lines earlier in the file. The context region is
meant to help find how to adjust the line numbers in order to apply the changes to the right lines. However,
if multiple areas of the code have the same surrounding lines of context, the wrong one can be picked. There
are real-world cases where this has caused commits to be reapplied incorrectly with no conflicts reported.
Setting diff.context to a larger value may prevent such types of problems, but increases the chance of
spurious conflicts (since it will require more lines of matching context to apply).
The merge backend works with a full copy of each relevant file, insulating it from these types of problems.
LLaabbeelllliinngg ooff ccoonnfflliiccttss mmaarrkkeerrss
When there are content conflicts, the merge machinery tries to annotate each side’s conflict markers with the
commits where the content came from. Since the apply backend drops the original information about the rebased
commits and their parents (and instead generates new fake commits based off limited information in the
generated patches), those commits cannot be identified; instead it has to fall back to a commit summary. Also,
when merge.conflictStyle is set to diff3, the apply backend will use "constructed merge base" to label the
content from the merge base, and thus provide no information about the merge base commit whatsoever.
The merge backend works with the full commits on both sides of history and thus has no such limitations.
HHooookkss
The apply backend has not traditionally called the post-commit hook, while the merge backend has. Both have
called the post-checkout hook, though the merge backend has squelched its output. Further, both backends only
call the post-checkout hook with the starting point commit of the rebase, not the intermediate commits nor the
final commit. In each case, the calling of these hooks was by accident of implementation rather than by design
(both backends were originally implemented as shell scripts and happened to invoke other commands like _g_i_t
_c_h_e_c_k_o_u_t or _g_i_t _c_o_m_m_i_t that would call the hooks). Both backends should have the same behavior, though it is
not entirely clear which, if any, is correct. We will likely make rebase stop calling either of these hooks in
the future.
IInntteerrrruuppttaabbiilliittyy
The apply backend has safety problems with an ill-timed interrupt; if the user presses Ctrl-C at the wrong
time to try to abort the rebase, the rebase can enter a state where it cannot be aborted with a subsequent ggiitt
rreebbaassee ----aabboorrtt. The merge backend does not appear to suffer from the same shortcoming. (See
hhttttppss::////lloorree..kkeerrnneell..oorrgg//ggiitt//2200220000220077113322115522..GGCC22886688@@sszzeeddeerr..ddeevv// for details.)
CCoommmmiitt RReewwoorrddiinngg
When a conflict occurs while rebasing, rebase stops and asks the user to resolve. Since the user may need to
make notable changes while resolving conflicts, after conflicts are resolved and the user has run ggiitt rreebbaassee
----ccoonnttiinnuuee, the rebase should open an editor and ask the user to update the commit message. The merge backend
does this, while the apply backend blindly applies the original commit message.
MMiisscceellllaanneeoouuss ddiiffffeerreenncceess
There are a few more behavioral differences that most folks would probably consider inconsequential but which
are mentioned for completeness:
• Reflog: The two backends will use different wording when describing the changes made in the reflog, though
both will make use of the word "rebase".
• Progress, informational, and error messages: The two backends provide slightly different progress and
informational messages. Also, the apply backend writes error messages (such as "Your files would be
overwritten...") to stdout, while the merge backend writes them to stderr.
• State directories: The two backends keep their state in different directories under .git/
MMEERRGGEE SSTTRRAATTEEGGIIEESS
The merge mechanism (ggiitt mmeerrggee and ggiitt ppuullll commands) allows the backend _m_e_r_g_e _s_t_r_a_t_e_g_i_e_s to be chosen with --ss
option. Some strategies can also take their own options, which can be passed by giving --XX<<ooppttiioonn>> arguments to
ggiitt mmeerrggee and/or ggiitt ppuullll.
resolve
This can only resolve two heads (i.e. the current branch and another branch you pulled from) using a 3-way
merge algorithm. It tries to carefully detect criss-cross merge ambiguities and is considered generally
safe and fast.
recursive
This can only resolve two heads using a 3-way merge algorithm. When there is more than one common ancestor
that can be used for 3-way merge, it creates a merged tree of the common ancestors and uses that as the
reference tree for the 3-way merge. This has been reported to result in fewer merge conflicts without
causing mismerges by tests done on actual merge commits taken from Linux 2.6 kernel development history.
Additionally this can detect and handle merges involving renames, but currently cannot make use of
detected copies. This is the default merge strategy when pulling or merging one branch.
The _r_e_c_u_r_s_i_v_e strategy can take the following options:
ours
This option forces conflicting hunks to be auto-resolved cleanly by favoring _o_u_r version. Changes from
the other tree that do not conflict with our side are reflected in the merge result. For a binary
file, the entire contents are taken from our side.
This should not be confused with the _o_u_r_s merge strategy, which does not even look at what the other
tree contains at all. It discards everything the other tree did, declaring _o_u_r history contains all
that happened in it.
theirs
This is the opposite of _o_u_r_s; note that, unlike _o_u_r_s, there is no _t_h_e_i_r_s merge strategy to confuse
this merge option with.
patience
With this option, _m_e_r_g_e_-_r_e_c_u_r_s_i_v_e spends a little extra time to avoid mismerges that sometimes occur
due to unimportant matching lines (e.g., braces from distinct functions). Use this when the branches
to be merged have diverged wildly. See also ggiitt--ddiiffff(1) ----ppaattiieennccee.
diff-algorithm=[patience|minimal|histogram|myers]
Tells _m_e_r_g_e_-_r_e_c_u_r_s_i_v_e to use a different diff algorithm, which can help avoid mismerges that occur due
to unimportant matching lines (such as braces from distinct functions). See also ggiitt--ddiiffff(1)
----ddiiffff--aallggoorriitthhmm.
ignore-space-change, ignore-all-space, ignore-space-at-eol, ignore-cr-at-eol
Treats lines with the indicated type of whitespace change as unchanged for the sake of a three-way
merge. Whitespace changes mixed with other changes to a line are not ignored. See also ggiitt--ddiiffff(1) --bb,
--ww, ----iiggnnoorree--ssppaaccee--aatt--eeooll, and ----iiggnnoorree--ccrr--aatt--eeooll.
• If _t_h_e_i_r version only introduces whitespace changes to a line, _o_u_r version is used;
• If _o_u_r version introduces whitespace changes but _t_h_e_i_r version includes a substantial change,
_t_h_e_i_r version is used;
• Otherwise, the merge proceeds in the usual way.
renormalize
This runs a virtual check-out and check-in of all three stages of a file when resolving a three-way
merge. This option is meant to be used when merging branches with different clean filters or
end-of-line normalization rules. See "Merging branches with differing checkin/checkout attributes" in
ggiittaattttrriibbuutteess(5) for details.
no-renormalize
Disables the rreennoorrmmaalliizzee option. This overrides the mmeerrggee..rreennoorrmmaalliizzee configuration variable.
no-renames
Turn off rename detection. This overrides the mmeerrggee..rreennaammeess configuration variable. See also ggiitt--
ddiiffff(1) ----nnoo--rreennaammeess.
find-renames[=<n>]
Turn on rename detection, optionally setting the similarity threshold. This is the default. This
overrides the _m_e_r_g_e_._r_e_n_a_m_e_s configuration variable. See also ggiitt--ddiiffff(1) ----ffiinndd--rreennaammeess.
rename-threshold=<n>
Deprecated synonym for ffiinndd--rreennaammeess==<<nn>>.
subtree[=<path>]
This option is a more advanced form of _s_u_b_t_r_e_e strategy, where the strategy makes a guess on how two
trees must be shifted to match with each other when merging. Instead, the specified path is prefixed
(or stripped from the beginning) to make the shape of two trees to match.
octopus
This resolves cases with more than two heads, but refuses to do a complex merge that needs manual
resolution. It is primarily meant to be used for bundling topic branch heads together. This is the default
merge strategy when pulling or merging more than one branch.
ours
This resolves any number of heads, but the resulting tree of the merge is always that of the current
branch head, effectively ignoring all changes from all other branches. It is meant to be used to supersede
old development history of side branches. Note that this is different from the -Xours option to the
_r_e_c_u_r_s_i_v_e merge strategy.
subtree
This is a modified recursive strategy. When merging trees A and B, if B corresponds to a subtree of A, B
is first adjusted to match the tree structure of A, instead of reading the trees at the same level. This
adjustment is also done to the common ancestor tree.
With the strategies that use 3-way merge (including the default, _r_e_c_u_r_s_i_v_e), if a change is made on both
branches, but later reverted on one of the branches, that change will be present in the merged result; some
people find this behavior confusing. It occurs because only the heads and the merge base are considered when
performing a merge, not the individual commits. The merge algorithm therefore considers the reverted change as
no change at all, and substitutes the changed version instead.
NNOOTTEESS
You should understand the implications of using _g_i_t _r_e_b_a_s_e on a repository that you share. See also RECOVERING
FROM UPSTREAM REBASE below.
When the git-rebase command is run, it will first execute a "pre-rebase" hook if one exists. You can use this
hook to do sanity checks and reject the rebase if it isn’t appropriate. Please see the template pre-rebase
hook script for an example.
Upon completion, <branch> will be the current branch.
IINNTTEERRAACCTTIIVVEE MMOODDEE
Rebasing interactively means that you have a chance to edit the commits which are rebased. You can reorder the
commits, and you can remove them (weeding out bad or otherwise unwanted patches).
The interactive mode is meant for this type of workflow:
1. have a wonderful idea
2. hack on the code
3. prepare a series for submission
4. submit
where point 2. consists of several instances of
a) regular use
1. finish something worthy of a commit
2. commit
b) independent fixup
1. realize that something does not work
2. fix that
3. commit it
Sometimes the thing fixed in b.2. cannot be amended to the not-quite perfect commit it fixes, because that
commit is buried deeply in a patch series. That is exactly what interactive rebase is for: use it after plenty
of "a"s and "b"s, by rearranging and editing commits, and squashing multiple commits into one.
Start it with the last commit you want to retain as-is:
git rebase -i <after-this-commit>
An editor will be fired up with all the commits in your current branch (ignoring merge commits), which come
after the given commit. You can reorder the commits in this list to your heart’s content, and you can remove
them. The list looks more or less like this:
pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...
The oneline descriptions are purely for your pleasure; _g_i_t _r_e_b_a_s_e will not look at them but at the commit
names ("deadbee" and "fa1afe1" in this example), so do not delete or edit the names.
By replacing the command "pick" with the command "edit", you can tell _g_i_t _r_e_b_a_s_e to stop after applying that
commit, so that you can edit the files and/or the commit message, amend the commit, and continue rebasing.
To interrupt the rebase (just like an "edit" command would do, but without cherry-picking any commit first),
use the "break" command.
If you just want to edit the commit message for a commit, replace the command "pick" with the command
"reword".
To drop a commit, replace the command "pick" with "drop", or just delete the matching line.
If you want to fold two or more commits into one, replace the command "pick" for the second and subsequent
commits with "squash" or "fixup". If the commits had different authors, the folded commit will be attributed
to the author of the first commit. The suggested commit message for the folded commit is the concatenation of
the first commit’s message with those identified by "squash" commands, omitting the messages of commits
identified by "fixup" commands, unless "fixup -c" is used. In that case the suggested commit message is only
the message of the "fixup -c" commit, and an editor is opened allowing you to edit the message. The contents
(patch) of the "fixup -c" commit are still incorporated into the folded commit. If there is more than one
"fixup -c" commit, the message from the final one is used. You can also use "fixup -C" to get the same
behavior as "fixup -c" except without opening an editor.
_g_i_t _r_e_b_a_s_e will stop when "pick" has been replaced with "edit" or when a command fails due to merge errors.
When you are done editing and/or resolving conflicts you can continue with ggiitt rreebbaassee ----ccoonnttiinnuuee.
For example, if you want to reorder the last 5 commits, such that what was HEAD~4 becomes the new HEAD. To
achieve that, you would call _g_i_t _r_e_b_a_s_e like this:
$ git rebase -i HEAD~5
And move the first patch to the end of the list.
You might want to recreate merge commits, e.g. if you have a history like this:
X
\
A---M---B
/
---o---O---P---Q
Suppose you want to rebase the side branch starting at "A" to "Q". Make sure that the current HEAD is "B", and
call
$ git rebase -i -r --onto Q O
Reordering and editing commits usually creates untested intermediate steps. You may want to check that your
history editing did not break anything by running a test, or at least recompiling at intermediate points in
history by using the "exec" command (shortcut "x"). You may do so by creating a todo list like this one:
pick deadbee Implement feature XXX
fixup f1a5c00 Fix to feature XXX
exec make
pick c0ffeee The oneline of the next commit
edit deadbab The oneline of the commit after
exec cd subdir; make test
...
The interactive rebase will stop when a command fails (i.e. exits with non-0 status) to give you an
opportunity to fix the problem. You can continue with ggiitt rreebbaassee ----ccoonnttiinnuuee.
The "exec" command launches the command in a shell (the one specified in $$SSHHEELLLL, or the default shell if
$$SSHHEELLLL is not set), so you can use shell features (like "cd", ">", ";" ...). The command is run from the root
of the working tree.
$ git rebase -i --exec "make test"
This command lets you check that intermediate commits are compilable. The todo list becomes like that:
pick 5928aea one
exec make test
pick 04d0fda two
exec make test
pick ba46169 three
exec make test
pick f4593f9 four
exec make test
SSPPLLIITTTTIINNGG CCOOMMMMIITTSS
In interactive mode, you can mark commits with the action "edit". However, this does not necessarily mean that
_g_i_t _r_e_b_a_s_e expects the result of this edit to be exactly one commit. Indeed, you can undo the commit, or you
can add other commits. This can be used to split a commit into two:
• Start an interactive rebase with ggiitt rreebbaassee --ii <<ccoommmmiitt>>^^, where <commit> is the commit you want to split.
In fact, any commit range will do, as long as it contains that commit.
• Mark the commit you want to split with the action "edit".
• When it comes to editing that commit, execute ggiitt rreesseett HHEEAADD^^. The effect is that the HEAD is rewound by
one, and the index follows suit. However, the working tree stays the same.
• Now add the changes to the index that you want to have in the first commit. You can use ggiitt aadddd (possibly
interactively) or _g_i_t _g_u_i (or both) to do that.
• Commit the now-current index with whatever commit message is appropriate now.
• Repeat the last two steps until your working tree is clean.
• Continue the rebase with ggiitt rreebbaassee ----ccoonnttiinnuuee.
If you are not absolutely sure that the intermediate revisions are consistent (they compile, pass the
testsuite, etc.) you should use _g_i_t _s_t_a_s_h to stash away the not-yet-committed changes after each commit, test,
and amend the commit if fixes are necessary.
RREECCOOVVEERRIINNGG FFRROOMM UUPPSSTTRREEAAMM RREEBBAASSEE
Rebasing (or any other form of rewriting) a branch that others have based work on is a bad idea: anyone
downstream of it is forced to manually fix their history. This section explains how to do the fix from the
downstream’s point of view. The real fix, however, would be to avoid rebasing the upstream in the first place.
To illustrate, suppose you are in a situation where someone develops a _s_u_b_s_y_s_t_e_m branch, and you are working
on a _t_o_p_i_c that is dependent on this _s_u_b_s_y_s_t_e_m. You might end up with a history like the following:
o---o---o---o---o---o---o---o master
\
o---o---o---o---o subsystem
\
*---*---* topic
If _s_u_b_s_y_s_t_e_m is rebased against _m_a_s_t_e_r, the following happens:
o---o---o---o---o---o---o---o master
\ \
o---o---o---o---o o'--o'--o'--o'--o' subsystem
\
*---*---* topic
If you now continue development as usual, and eventually merge _t_o_p_i_c to _s_u_b_s_y_s_t_e_m, the commits from _s_u_b_s_y_s_t_e_m
will remain duplicated forever:
o---o---o---o---o---o---o---o master
\ \
o---o---o---o---o o'--o'--o'--o'--o'--M subsystem
\ /
*---*---*-..........-*--* topic
Such duplicates are generally frowned upon because they clutter up history, making it harder to follow. To
clean things up, you need to transplant the commits on _t_o_p_i_c to the new _s_u_b_s_y_s_t_e_m tip, i.e., rebase _t_o_p_i_c.
This becomes a ripple effect: anyone downstream from _t_o_p_i_c is forced to rebase too, and so on!
There are two kinds of fixes, discussed in the following subsections:
Easy case: The changes are literally the same.
This happens if the _s_u_b_s_y_s_t_e_m rebase was a simple rebase and had no conflicts.
Hard case: The changes are not the same.
This happens if the _s_u_b_s_y_s_t_e_m rebase had conflicts, or used ----iinntteerraaccttiivvee to omit, edit, squash, or fixup
commits; or if the upstream used one of ccoommmmiitt ----aammeenndd, rreesseett, or a full history rewriting command like
ffiilltteerr--rreeppoo[2].
TThhee eeaassyy ccaassee
Only works if the changes (patch IDs based on the diff contents) on _s_u_b_s_y_s_t_e_m are literally the same before
and after the rebase _s_u_b_s_y_s_t_e_m did.
In that case, the fix is easy because _g_i_t _r_e_b_a_s_e knows to skip changes that are already present in the new
upstream (unless ----rreeaappppllyy--cchheerrrryy--ppiicckkss is given). So if you say (assuming you’re on _t_o_p_i_c)
$ git rebase subsystem
you will end up with the fixed history
o---o---o---o---o---o---o---o master
\
o'--o'--o'--o'--o' subsystem
\
*---*---* topic
TThhee hhaarrdd ccaassee
Things get more complicated if the _s_u_b_s_y_s_t_e_m changes do not exactly correspond to the ones before the rebase.
NNoottee
While an "easy case recovery" sometimes appears to be successful even in the hard case, it may have
unintended consequences. For example, a commit that was removed via ggiitt rreebbaassee ----iinntteerraaccttiivvee will be
rreessuurrrreecctteedd!
The idea is to manually tell _g_i_t _r_e_b_a_s_e "where the old _s_u_b_s_y_s_t_e_m ended and your _t_o_p_i_c began", that is, what
the old merge base between them was. You will have to find a way to name the last commit of the old _s_u_b_s_y_s_t_e_m,
for example:
• With the _s_u_b_s_y_s_t_e_m reflog: after _g_i_t _f_e_t_c_h, the old tip of _s_u_b_s_y_s_t_e_m is at ssuubbssyysstteemm@@{{11}}. Subsequent
fetches will increase the number. (See ggiitt--rreefflloogg(1).)
• Relative to the tip of _t_o_p_i_c: knowing that your _t_o_p_i_c has three commits, the old tip of _s_u_b_s_y_s_t_e_m must be
ttooppiicc~~33.
You can then transplant the old ssuubbssyysstteemm....ttooppiicc to the new tip by saying (for the reflog case, and assuming
you are on _t_o_p_i_c already):
$ git rebase --onto subsystem subsystem@{1}
The ripple effect of a "hard case" recovery is especially bad: _e_v_e_r_y_o_n_e downstream from _t_o_p_i_c will now have to
perform a "hard case" recovery too!
RREEBBAASSIINNGG MMEERRGGEESS
The interactive rebase command was originally designed to handle individual patch series. As such, it makes
sense to exclude merge commits from the todo list, as the developer may have merged the then-current mmaasstteerr
while working on the branch, only to rebase all the commits onto mmaasstteerr eventually (skipping the merge
commits).
However, there are legitimate reasons why a developer may want to recreate merge commits: to keep the branch
structure (or "commit topology") when working on multiple, inter-related branches.
In the following example, the developer works on a topic branch that refactors the way buttons are defined,
and on another topic branch that uses that refactoring to implement a "Report a bug" button. The output of ggiitt
lloogg ----ggrraapphh ----ffoorrmmaatt==%%ss --55 may look like this:
* Merge branch 'report-a-bug'
|\
| * Add the feedback button
* | Merge branch 'refactor-button'
|\ \
| |/
| * Use the Button class for all buttons
| * Extract a generic Button class from the DownloadButton one
The developer might want to rebase those commits to a newer mmaasstteerr while keeping the branch topology, for
example when the first topic branch is expected to be integrated into mmaasstteerr much earlier than the second one,
say, to resolve merge conflicts with changes to the DownloadButton class that made it into mmaasstteerr.
This rebase can be performed using the ----rreebbaassee--mmeerrggeess option. It will generate a todo list looking like this:
label onto
# Branch: refactor-button