10

git rebase在将文件添加到存储库,然后从存储库中删除,然后添加到工作目录(但不是存储库)的某些情况下,似乎无法正常工作。

这是对我的问题的更具体的描述:

  • 如果创建了一个分支并从某个主干切换到,

  • 并且在分支中添加并提交了一个文件 X,

  • 随后 X 被删除并提交到分支中,

  • 并且 X 再次在工作目录中创建,但未添加或提交,

  • 和主干分支前进,

  • 然后

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

  • 即使工作目录 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、removebar.txtgit rebase master再次中止 rebase。但是我怎样才能在不先中止它的情况下继续 rebase 呢?

4

5 回答 5

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
于 2010-09-24T17:22:37.223 回答
2

您需要在尝试变基之前提交。如果你不这样做,它有时会起作用,但你不应该那样做。

如果由于某种原因您对提交感到不舒服,您至少可以使用 stash (它的作用大致相同)。

于 2010-09-15T20:17:22.360 回答
2

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

似乎没有办法只重试最近的变基步骤。通常当一个 rebase 暂停时,它会在索引中留下冲突。但在这种情况下,它不能在索引中标记此问题,因为这样做会将您的未跟踪文件转换为已跟踪文件。这可能是git rebase. 你可以深入到它用来存储内部状态的目录.git/rebase-apply


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


暂时将冲突的文件移到一边并重做变基。

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

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

: "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/
)
于 2010-09-22T04:04:46.837 回答
0

为了让 GIT 在文件删除后继续进行 rebase,我添加了一个空格更改,然后“git add”带有该更改的文件。

于 2010-09-21T23:27:46.463 回答
0

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

我们将 SmartGit 用于我们的客户端,发生的情况是,即使 SmartGit 显示一个干净的 repo,a 也会git status显示一些已修改的随机文件。

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

我决定把它写在这里以备将来参考。Ofc,我假设您提交了您的有意更改,并且您可以丢弃无意识的更改。如果是这种情况,git checkout .应该(希望)这样做。

干杯

于 2015-08-24T20:13:41.457 回答