反正有没有删除一个分支几个连续提交?修剪几个连续提交
让我们说,历史是这样的:
A -> B -> C -> D
现在,我想删除B,C所带来的变化,所以历史上的样子:
A -> D
例如,典型的情况是,在提交B和C致力于垃圾醉酒开发商,而在D.
写的好东西,我想出了一个相当差的(也可能不是非常可靠的方法要做到这一点):
# Get a patch for the good things
# Context lines are set to zero so applying
# the patch won't choke because of missing lines
# that were added by C or D
git format-patch --stdout -U0 revC..revD > CtoD
# Go back in time to last good revision before mayhem
git reset --hard revA
# Apply good things at this point
git apply --stat CtoD
git apply --check CtoD
git apply CtoD
# Add new files from patch
git add <any files that were created in CtoD patch>
# And commit
git commit -a -m "Removed B and C commits. Drunk dev fired"
这样做并不完美。删除背景的差异可能会做出许多情况下混帐申请扼流圈和文件必须由手工混帐add'ed。 我也可能错过了这一点完全在这里...
有人能指出我这样做的正确方法?
感谢您的阅读!
编辑:
我忘了说了,我要所有这些东西推送到远程仓库,所以我尝试RAFL建议,虽然它在克隆好吧,这是不可能的正确地将东西推到原点。
这里是什么已经做了详细的(长,对不起!)名单:
##
# Create test environment
##
# all will happen below 'testing', so the mess can easily be wiped out
mkdir testing
cd testing
# Create 'origin' (sandbox_project) and the working clone (work)
mkdir sandbox_project work
# Create origin repos
cd sandbox_project
git init --bare
# Clone it
cd ../work
git clone ../sandbox_project
cd sandbox_project
# Create a few files :
# at each rev (A, B, C, D) we respectively create a fileA .. fileD
# at each rev, we also add a line to fileA
echo "This file was created in A" > fileA
git add .
git commit -a -m 'First revision'
git tag "revA"
for i in B C D; do
echo "This file was created in $i" >> file$i
echo "This change was done in $i" >> fileA
git add file$i
git commit -a -m "revision $i"
git tag "rev$i"
done
# We push changes to origin
git push origin master
现在,它看起来像这样:
$ git log --graph --decorate --pretty=oneline --abbrev-commit
* e3dc9b7 (HEAD, revD, origin/master, master) revision D
* e21fd6a (revC) revision C
* a9192ec (revB) revision B
* a16c9dd (revA) First revision
我想删除什么了在B和C介绍:
$ git rebase -i HEAD~3
Automatic cherry-pick failed. After resolving the conflicts,
mark the corrected paths with 'git add <paths>', and
run 'git rebase --continue'
Could not apply e3dc9b7... revision D
$ git status
# Not currently on any branch.
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: fileD
#
# Unmerged paths:
# (use "git reset HEAD <file>..." to unstage)
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: fileA
#
当然,存在具有的fileA的问题(问题我通过施加与我的解决办法来解决用-U0生成的diff。 在这里,我编辑的fileA,删除冲突的线,并继续底垫:
This file was created in A
<<<<<<< HEAD
=======
This change was done in B
This change was done in C
This change was done in D
>>>>>>> e3dc9b7... revision D
被编辑成:
This file was created in A
This change was done in D
然后:
$ git add fileA
$ git rebase --continue
# leave mesasge as-is
[detached HEAD e2d4032] revision D
2 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644 fileD
Successfully rebased and updated refs/heads/master.
$ git push
To ../sandbox_project
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to '../sandbox_project'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again. See the 'Note about
fast-forwards' section of 'git push --help' for details.
嗯,这看起来正常我,因为我重订基期,所以我尝试:
$ git pull
Auto-merging fileA
CONFLICT (content): Merge conflict in fileA
Automatic merge failed; fix conflicts and then commit the result.
$ git log --graph --decorate --pretty=oneline --abbrev-commit
* e2d4032 (HEAD, master) revision D
* a16c9dd (revA) First revision
再次,fileA不能合并,因为它有修订B和C cruft。在这里,我们再次去编辑fileA,并删除由C和C引入的更改。
然后:
$ git add fileA
$ git commit -a
[master b592261] Merge branch 'master' of ../sandbox_project
$ git push
Counting objects: 9, done.
Compressing objects: 100% (5/5), done.
Unpacking objects: 100% (5/5), done.
Writing objects: 100% (5/5), 674 bytes, done.
Total 5 (delta 0), reused 0 (delta 0)
To ../sandbox_project
e3dc9b7..b592261 master -> master
看起来不错,但:
$ git log --graph --decorate --pretty=oneline --abbrev-commit
* b592261 (HEAD, origin/master, master) Merge branch 'master' of ../sandbox_project
|\
| * e3dc9b7 (revD) revision D
| * e21fd6a (revC) revision C
| * a9192ec (revB) revision B
* | e2d4032 revision D
|/
* a16c9dd (revA) First revision
虽然在最后,的fileA是好的,我仍然有FILEB和fileC我不想。在过程中,我必须解决两次fileA的合并冲突。
任何线索?
感谢RAFL你的答案。虽然这对克隆工作正常,但我无法将更改推送给原始主数据。我很抱歉没有提到我必须将这些更改推送到远程存储库,对此抱歉。我编辑我的问题更清楚。谢谢 ! – leucos 2010-10-06 10:38:52
推进,这将是一个非快进,你已经改写历史公布。你可以强迫推,也可以采用不同的方式,因为我会在一秒之内回答我的答案。你应该阅读一般重写历史和非快进的内容。 – rafl 2010-10-06 10:42:43
谢谢拉夫,这是诀窍。恢复这两个提交,沿着解决方案编辑fileA做我想要的。我需要确认! – leucos 2010-10-06 14:33:34