最简单和最快速的解决方案就是你已经想出来的那个。你可以将步骤1和2结合起来。
git rebase master feature/2
如果可以轻松计算目标提交的表达式,您可能会发现避免处理提交ID更容易(例如您的示例情况)。
git branch -f feature/1 feature/2^
feature/1
进行变基,然后在feature/1
上变基feature/2
的特定技术依赖于第二个变基期间重复补丁ID的检测,如果在第一个变基期间发生任何冲突解决,则会以不幸的方式失败。如果您真的想使用两个rebase方法,我建议第二个rebase应该像这样完成。git rebase --onto feature/1 feature/1@{1} feature/2
为了避免重新编写feature/1
提交记录,建议使用这种方法。(feature/1@{1}
是指在重置之前指向feature/1
的reflog条目。)但是,这样做需要使用较不常见的rebase语法,据我所知,它至少与您最初执行的操作一样“不简单”。
或者,您可以使用--fork-point
选项,让git自动解释reflog并尝试找出哪些提交记录是重复的。
git rebase --fork-point feature/1 feature/2
git rebase master feature/1
git rebase feature/1 feature/2
就像这样,你可以复制并粘贴:
git init test; cd $_
doit() { eval echo \>$*; git add $1; git commit -m "$2"; }
doit master "Initial commit"
git checkout -tb feature/1
doit file1 "Feature 1"
git checkout -tb feature/2
doit file2 "Feature 2"
git checkout master
doit master "New commit on master"
精确地绘制您的图表:
$ git log --graph --decorate --oneline --all
* 35cfad5 (feature/2) Feature 2
* 46b79ae (feature/1) Feature 1
| * ae89e31 (HEAD -> master) New commit on master
|/
* f1138eb Initial commit
$
现在,既然你已经告诉 Git 你的分支结构了,
$ git rebase master feature/1
First, rewinding head to replay your work on top of it...
Applying: Feature 1
$ git rebase feature/1 feature/2
First, rewinding head to replay your work on top of it...
Applying: Feature 2
$
rebase <upstream> <source>
。您所说的 upstream
是什么意思?我们在这里没有涉及远程存储库,除非我理解错了,否则 upstream
指的是该远程存储库(如 origin)。 - Kuba Szymanowskiupstream
可能源于这样一种用例,即您正在将本地更改移动到远程(如使用 pull --rebase
)以进行追赶;更普遍地说,它通常意味着“我的”更改(我正在重写的更改)分叉的分支。从技术层面上讲,它的意思是“在选择要重写的提交时,排除此提交及其可达的任何提交,因为它们在我正在重写的提交的上游(拓扑)”。 - Mark Adelsbergerfeature/2
可达但不再可达于feature/1
的所有内容重新定位。但是不要相信我的话-我已经多次描述了失败条件。运行测试。 - Mark Adelsberger
zsh: no matches found: feature/2^
- Kuba Szymanowskifeature/2^
用引号括起来就可以了。 - Kuba Szymanowskifeature/1@{1}
的语法或者指向相关资源吗? - Kuba Szymanowskifeature/1@{1}
是一个 reflog 表达式。它只在第一次变基发生的特定存储库中起作用(reflogs 是本地的,因此其他克隆看不到它),而且您还必须知道 reflogs 过期了(但默认是保留它们一段相当长的时间)。但基本上它表示“查看feature/1
指向的位置的历史记录,在过去往后退一步”。请参见https://git-scm.com/docs/git-reflog。 - Mark Adelsberger