git rebase,“会被覆盖”,“没有变化 - 你忘了使用'git add'吗?”

时间:2010-09-15 19:02:20

标签: git git-rebase

在将某个文件添加到存储库,然后从存储库中删除,然后添加到工作目录(但不是存储库)的某些情况下,

git rebase似乎无法正常工作。

以下是我的问题的更具体描述:

  • 如果创建分支并从某些分支切换到 躯干,

  • 并添加并提交文件X. 在分公司,

  • 随后删除X并且 在分公司承诺,

  • 在工作中再次创建X. 目录,但没有添加或 提交,

  • 并且主干分支前进,

  • 然后

  • 使用高级执行的rebase 作为基地的主干将失败,因为 它会拒绝覆盖X,

  • 并且不能继续使用rebase 即使工作目录X是 移除或移开。

这是一个在命令行上重现我的问题的脚本:

git init
echo foo > foo.txt
git add .
git commit -m 'foo'
echo foo >> foo.txt
git add .
git commit -m 'foo foo'
git checkout -b topic HEAD^
git log
echo bar > bar.txt
echo baz > baz.txt
git add .
git commit -m 'bar baz'
git rm bar.txt
git commit -m '-bar' 
echo bar > bar.txt
git rebase master 
# the following output is emitted:
# First, rewinding head to replay your work on top of it...
# Applying: bar baz
# Using index info to reconstruct a base tree...
# Falling back to patching base and 3-way merge...
# error: Untracked working tree file 'bar.txt' would be overwritten by merge.  Aborting
# Failed to merge in the changes.
# Patch failed at 0001 bar baz
# 
# When you have resolved this problem run "git rebase --continue".
rm bar.txt
git rebase --continue
# the following output is emitted:
# Applying: bar baz
# No changes - did you forget to use 'git add'?
# 
# When you have resolved this problem run "git rebase --continue".
# If you would prefer to skip this patch, instead run "git rebase --skip".
# To restore the original branch and stop rebasing run "git rebase --abort".

我知道我可以使用git rebase --abort中止变种,删除bar.txt,然后再次git rebase master。但是,如何在不中止的情况下继续使用rebase?

5 个答案:

答案 0 :(得分:4)

我找到了一个解决方案:手动应用有问题的提交补丁并将其添加到索引中。

$ patch -p1 < .git/rebase-apply/patch 
patching file bar.txt
patching file baz.txt
$ git add bar.txt baz.txt
$ git rebase --continue
Applying: bar baz
Applying: -bar

答案 1 :(得分:2)

您需要在尝试重新绑定之前提交。如果你不这样做,它会工作,但你不应该这样做。

如果你出于某种原因感到不舒服,你至少可以使用藏匿处(大致相同的东西)。

答案 2 :(得分:2)

git rebase工作正常。它正在保护您未跟踪的文件在访问想要写出具有相同路径名的文件的提交时被销毁。

似乎没有办法只重试rebase的最新步骤。通常当rebase暂停时,它会在索引中留下冲突。但在这种情况下,它无法在索引中标记此问题,因为这样做会将未跟踪的文件转换为跟踪文件。这可能是git rebase的UI中的一个粗略位置。您可以深入了解它用于存储其内部状态(.git/rebase-apply)的目录并手动应用“当前”补丁,但是中止和重启可能更容易(但如果您正在进行重新定位,则可能不会更快)很长的系列)。


如果添加bar.txt被视为错误,那么您可以考虑使用git rebase -i来分开并删除bar.txt的添加和删除,因为您无论如何都要重写历史记录。登记/> 您仍然会遇到冲突,但下面的方法也可以应用git rebase -i。最后的脚本必须分成两部分(“setup temp/”和“合并rebase结果”,因为交互式rebase通常需要在这两个部分之间有多个命令。


暂时将冲突文件移到一边并重做rebase。

mv bar.txt +bar.txt
git rebase --abort
git rebase master

如果您期望许多这样的冲突文件,那么您可以考虑在单独的克隆中进行rebase,在那里您可以确定您没有任何未跟踪的文件。也许最棘手的部分是检查您的未跟踪文件是否与rebase的结果不冲突(git checkout rebased-topic完成此操作;如果未跟踪的文件与rebase结果冲突,它将中止。)

: "Note: will destroy
:     * 'rebased-topic' branch
:     * 'temp' directory"
( set -x &&
  : '*** Clearing temp/' &&
  rm -rf temp/ &&

  : '*** Making sure we have topic checked out' &&
  git checkout topic

  : '*** Cloning into temp/' &&
  git clone . temp && 

  : '*** Rebasing topic onto master in temp/ clone' &&
  ( cd temp &&
  git rebase origin/master
  ) &&

  : '*** Fetching rebase result from topic/ into local rebased-topic branch' &&
  git fetch -f temp topic:rebased-topic &&

  : '*** Checking rebased-topic for conflicts with untracked files' &&
  git checkout rebased-topic &&

  : '*** Resetting topic to tip of rebased-topic' &&
  git branch -f topic rebased-topic &&

  : '*** Returning to topic branch' &&
  git checkout topic &&

  : '*** Deleting rebased-topic branch' &&
  git branch -d rebased-topic &&

  : '*** Deleting temp/' &&
  rm -rf temp/
)

答案 3 :(得分:0)

为了让GIT在删除文件后继续使用rebase,我添加了空格更改,然后使用该更改“git add”该文件。

答案 4 :(得分:0)

这发生在我和几个团队成员身上很多次......通常是在同一个分支机构工作并经常提交。

我们将SmartGit用于我们的客户端,即使SmartGit显示一个干净的仓库,git status也显示了一些修改过的随机文件。

我刚刚再遇到这个,发现git checkout .为我解决了这个问题。它放弃了这些“看不见的本地更改”,让我继续拉动(并重新设置我的传出提交)。

我决定把它写在这里以供将来参考。 Ofc,我认为你已经做出了有意的改变,你可以放弃那些无意的改变。如果是这种情况,一个git checkout .应该(希望)这样做。

干杯