Git 在将分支重新定位到重写的历史上时,如何避免虚假的合并冲突?

Git 在将分支重新定位到重写的历史上时,如何避免虚假的合并冲突?,git,Git,在我的工作场所,我们使用一个重设基础的工作流。我最近帮助了三位同事解决了以下问题,因此我认为值得发布一个问答,以帮助更多的人,并为我的同事提供参考 假设我运行以下一系列命令来创建git存储库,并使用一些数据和一次提交对其进行初始化 git init . cat > MyFile.txt <<'EOF' > Line 1 > Line 2 > Line 3 > Line 4 > EOF git commit -m 'Initial commit'

在我的工作场所,我们使用一个重设基础的工作流。我最近帮助了三位同事解决了以下问题,因此我认为值得发布一个问答,以帮助更多的人,并为我的同事提供参考

假设我运行以下一系列命令来创建git存储库,并使用一些数据和一次提交对其进行初始化

git init .
cat > MyFile.txt <<'EOF'
> Line 1
> Line 2
> Line 3
> Line 4
> EOF
git commit -m 'Initial commit'
在将其发送以供审阅后,我将根据此功能开发一个不同的功能,并进行新的提交

git checkout -b MySecondFeature
cat >> ThisFileDependsOnMyFile.txt <<'EOF'
> This commit touches a completely different file.
> EOF
git add ThisFileDependsOnMyFile.txt
git commit -m 'Add Feature2'
最后,我尝试将我的SecondFeature重新设置为master。不幸的是,尽管MySecondFeature上的新commit甚至没有触及冲突的文件,但它还是崩溃了

git checkout MySecondFeature
git rebase master
First, rewinding head to replay your work on top of it...
Applying: WIP Add glorious feature
Using index info to reconstruct a base tree...
M       MyFile.txt
Falling back to patching base and 3-way merge...
Auto-merging MyFile.txt
CONFLICT (content): Merge conflict in MyFile.txt
error: Failed to merge in the changes.
Patch failed at 0001 WIP Add glorious feature
hint: Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".


有三种方法可以避免手动解决虚假合并冲突

跳过冲突提交 因为我们实际上并不关心F878084412C0454297CB5C52B0FB6F6A2B2870,所以我们可以在重基期间跳过它

git rebase master
# Bunch of merge 
git rebase --skip

明确告诉rebase要重新设置历史记录的哪一部分 这是我最喜欢的解决方案。您可以使用
--to
运行
git-rebase
,并传递目标分支,然后是我们关心的MySecondFeature上最早提交的父级

# Get out of the merge conflict situation
git rebase --abort

git rebase --onto master 061fc8448e93f0e31239b2f4806d5caac6bfe578~1
樱桃采摘 我们可以从我们想要的历史开始创建一个临时分支,并从MySecondFeature中选择我们想要的提交

# Get out of the merge conflict situation
git rebase --abort

git checkout -b TempBranch master
# Note that if there are multiple commits we care about on MySecond Feature, these should be cherry-picked either individually or together in the right order.
git cherry-pick MySecondFeature
git checkout MySecondFeature

# Note that this command will blow away changes in your working directory.
git reset --hard TempBranch

# git branch -d TempBranch


我喜欢使用交互式重基并删除不应该存在的任何提交:

git rebase -i master
您的git编辑器将打开一个文件,允许您重新排序、编辑和删除提交。在这种情况下,我们只想删除现在不存在的MyFeature提交,这是通过在提交哈希之前放置“drop”来完成的:

drop f878084 WIP Add glorious feature
pick 061fc84 Add Feature2

# Rebase 522cc62..061fc84 onto 522cc62 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
# Get out of the merge conflict situation
git rebase --abort

git checkout -b TempBranch master
# Note that if there are multiple commits we care about on MySecond Feature, these should be cherry-picked either individually or together in the right order.
git cherry-pick MySecondFeature
git checkout MySecondFeature

# Note that this command will blow away changes in your working directory.
git reset --hard TempBranch

# git branch -d TempBranch

git rebase -i master
drop f878084 WIP Add glorious feature
pick 061fc84 Add Feature2

# Rebase 522cc62..061fc84 onto 522cc62 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
Successfully rebased and updated refs/heads/MySecondFeature.