Fixing published branch with wrong parent branch
I ran into a problem where I published a branch to my public git repository that had the wrong parent branch. My attempts to fix this made things worse.
Initially, I had:
A <-- master
\
B <-- abstract-test-rule
\
C <-- run-leaf
I pushed abstract-test-rule and run-leaf to my public github repository, and made pull requests for each. I then realized that "run-leaf" included commit B; I had meant to branch "run-leaf" off of "A". So I ran git revert B
on branch "run-leaf":
A <-- master
\
B <-- abstract-test-rule
\
C--B' <-- run-leaf
I re-pushed "run-leaf" to my public github repository.
Question 1: What should I have done? I'm guessing the correct thing would be to create a new branch off of A with only the delta from commit C, pushed that to my public github repository, canceled the previous pull request and create a new one. What's the easiest way to do that?
Unfortunately, branch "run-leaf" was merged into the parent repository from commit C, and then B' was merged into the parent repo.
I knew the merge of "abstract-test-rule" would now be painful for the owner of the parent repository, so I tried to prepare "abstract-test-rule" for merge. By this time my repo looked like this:
A <-- master
\
开发者_高级运维 B--D--E <-- abstract-test-rule
\
C--B' <-- run-leaf
I went into my repo, pulled from the parent repo into "master", and then merged "master" into "abstract-test-rule". The merge was a mess (because, I'm guessing, I was merging the parent repo's version of B' into "abstract-test-rule"). After all this, we have some very confusing diffs.
Question 2: Was there an easier way for me to cleanup "abstract-test-rule"? In other words, I wanted to merge "master" into "abstract-test-rule" but avoid merging my parent repo's version of B' into "abstract-test-rule"
Question 3: What is the best way to verify that the merges to the parent repository were done correctly? Right now, I'm just pulling from the parent repository, merging my version of the branches from "master" (reviewing the diffs from the merge) and running git diff master
to verify that the branch is now identical to "master"
Thanks!
Question 1: What should I have done? I'm guessing the correct thing would be to create a new branch off of A with only the delta from commit C, pushed that to my public github repository, canceled the previous pull request and create a new one. What's the easiest way to do that?
It depends on if anyone has already pulled your changes. If no one has pulled your changes you can remove the branch and recreate a new one with the wanted commits. If your changes got into another repo you can only git revert
the unwanted commit. As a rule f thumb if you published the branch it is safer to git revert
since in most cases you can't be sure that no one pulled the unwanted branch.
edit: changeset transplanting
You can create a new branch with only the C changeset by either
git checkout -b newbranch A # <- branch name or commit-id
git cherry-pick SHA1(C) # repeat for every wanted commit
or
git checkout -b newbranch run-leaf
git rebase -i HEAD~10 # large-enough number to include every commit you want
# to strip, and remove every unwanted commit in the editor
Both ways create a new branch with only the wanted commits.
Question 2: Was there an easier way for me to cleanup "abstract-test-rule"? In other words, I wanted to merge "master" into "abstract-test-rule" but avoid merging my parent repo's version of B' into "abstract-test-rule"
As long as the changes are not published, you can git rebase -i
the branch history. When the changes are published you can't edit the history.
edit
As your changes are already spread out, so reverting the changeset is the recommended way. You could also have striped out the unwanted changeset with interactive rebase, and git push -f
this changes out, but every other who pulled the old branch would likely run into trouble on the next pull of your repo. See this SO question and the git docs for more information about that.
Question 3: What is the best way to verify that the merges to the parent repository were done correctly? Right now, I'm just pulling from the parent repository, merging my version of the branches from "master" (reviewing the diffs from the merge) and running git diff master to verify that the branch is now identical to "master"
You can do the merge on your side so that for the upstream developer these are fast forward merges. That way the upstream developer does no merge on it's own but uses your prepared merge.
精彩评论