我有一个带有主分支的回购和一个名为febupdate的分支。一周前(或左右)我向febupdate分支提交了一些新文件并将更新推送到github。从那时起,又有三个提交被推送到该分支。
然后有人回来说,几周前提交的所有文件都需要拔出(因为它们是其他数据的副本)。我不知道该怎么做,所以我要求提供一些建议并被告知git rebase HEAD~3
。所以我这样做了,我删除了错误的提交,我本地副本中的所有内容现在都应该如此。但我们无法弄清楚如何让github上的回购反映出来。最后我们做了git push --force
。
现在,只要有人对该分支进行git pull
,就会要求他们提供合并内容的原因。用户也会收到所有重复文件。我们唯一能做的就是吹掉整个文件夹,然后做一个新的git clone
。
以下是我的问题
git clone
?答案 0 :(得分:2)
首先,其他人不需要新的git clone
。如果他们知道这个“rebase”,他们可以使用
git fetch
git reset --hard origin/febupdate
关于你的第一个问题:
答案是否定的,为什么你的febupdate分支搞砸是因为“rebase”。 rebase导致git无法快速转发更改。对于master分支,我们只在将febupdate合并到它时添加新的提交。在这种情况下,其他人可以毫无问题地使用pull
。 (git可以快进)
所以我猜你知道问题2和3的答案。如果你只添加新的提交,其他人可以毫无问题地提取。要做到这一点,一个技巧是:
git status
将显示您删除了所需的文件,提交更改,推送答案 1 :(得分:1)
一旦每个人都有历史记录更新,合并问题应该停止。或者他们可以在分支上执行git reset --hard <sha before the reset>
并执行拉动(这将导致他们丢失他们拥有分支的任何提交)。他们应该通过创建一个新的分支来备份这些更改,他们可以使用这个分支来挑选他们的提交。
本文应该对正在发生的事情有所了解。为什么在推送提交上执行git rebase
是一件非常糟糕的事情。
http://git-scm.com/book/en/Git-Branching-Rebasing#The-Perils-of-Rebasing
下次要撤消已推送的更改时,应使用git revert <sha of commit>
。这将创建一个新提交,它是问题提交的反转。如果您只想撤消某些更改,请执行git checkout <sha of commit with good files> -- <files to fix>
并进行提交。
如果您推送了更改,则需要进行新的提交以修复更改,而不是尝试通过删除提交来修改历史记录。
答案 2 :(得分:0)
这是因为他们仍然拥有您在旧版哈希下的回购中恢复的对象。 Git必须将新提取的数据与图中的哈希值合并,它可能会要求您提交提交消息,因为它正在尝试快进合并。如果你能通过rm'ing可能更清洁的文件解决问题。
答案 3 :(得分:0)
按顺序:
他们不必重新克隆(虽然这样可行)但是他们必须做一些额外的工作。
当您执行rebase
时,您复制了旧提交。假设提交B
是您“删除”的那个:
A - B - C - D [old "febupdate", is what you pushed originally]
\
C'- D' <-- HEAD=febupdate
任何抓住第一个“推送”副本的人都有三个原始提交,B
C
和D
。然后当他们去获取更新时,他们会收到新的提交C'
和D'
。假设他们自己添加了提交E
。所以他们现在(在引入更新之前):
A - B - C - D <-- origin/febupdate
\
E <-- HEAD=febupdate
一旦他们引入您的更新,他们就会得到:
A - B - C - D - E <-- HEAD=febupdate
\
C'- D' <-- origin/febupdate
就git而言,当它看到这个新状态时,它认为他们写了提交B
,C
,D
和{ {1}}和你写了提交E
和C'
。 Git让他们有机会将他们的四次提交(D'
到B
)与你的两次合并。
即使他们没有进行新的提交E
,git仍然可以让他们有机会将“他们的”三次提交(E
到B
)与您的两次合并。实际上,这将“恢复”提交D
。
如果他们没有自己的提交(编辑:和当然没有未保存的工作!),他们只需强制执行B
即可轻松恢复匹配febupdate
:
origin/febupdate
如果他们做拥有他们自己的提交(例如$ git checkout febupdate; git fetch; git reset --hard origin/febupdate
),他们需要将这些(而不是任何待删除的)提交到新提示提交{ {1}},他们可以使用E
或D'
。后者在 1 上工作有点棘手,但是一下子就完成了所有事情。前者(git cherry-pick
)更容易思考:他们只需将git rebase --onto
重命名为cherry-pick
,创建新的本地分支febupdate
以跟踪oops
,然后{ {1}}每个提交(真正他们的提交)从febupdate
到新origin/febupdate
。
“正确”的方式是谁愿意做什么样的工作,以及你和他们是否愿意允许错误提交git cherry-pick
保留在提交历史中。如果每个人都愿意完成上述所有工作,并且确实不希望oops
保留,那就是这样做的方法。
如果febupdate
可以保留,并且您想让人们轻松,则可以使用B
。作业B
的作用是添加一个新的提交,其效果只是“撤消旧提交中的操作”。假设在提交B
中您添加了一个文件git revert
并从git revert
中移除了一条好的行。命令B
将进行提交,删除badfile
并将好行放回goodfile
。无论在git revert <sha-1-of-B>
中发生什么,都要恢复“取消”并添加新的提交:
badfile
每个人都希望添加新的提交,因此这“适用于”每个人已经拥有的工作流程。
排序,但是如果某些人已经抓住了提交goodfile
和B
,那么无论你现在做什么都会让某些人有额外的工作(超出他们已有的额外工作-工作)。在这种情况下,我可能只是继续让人们进行恢复(如上文第(1)部分所述)。
1 git 1.9 / 2.0中即将推出的功能应该(至少在理论上)使它不那么棘手。另外,作为一种特殊情况,A - B - C - D - R <-- HEAD=febupdate
在当前git中做正确的事情,但前提是你还没有运行C'
。 (这有点难以描述。)