Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add additional parents to old git commits?

I have a project containing two branches: master and gh-pages. They are essentially two different projects, where the gh-pages project depends on the master project (and not vice versa). Think of it as "master contains the source code, gh-pages contains the binary built from those source files". Periodically, I take the changes that have accumulated in master and make a new commit to the gh-pages branch with the commit message "Bring into line with master commit xxxxxxxx."

how the network graph currently looks

After a while of doing this, I realized that it would be nice if the gh-pages commit "Bring into line with master commit xxxxxxxx" actually had xxxxxxxx as its parent in the git repository. Like this (bad MSPaint art):

how it would ideally look

Is there a way to make the repository look like the second image above? I know how to make new commits follow this pattern: I can do "git merge -s ours master" (which sets the parents of an otherwise empty commit) followed by "git commit --amend adv550.z8" (where adv550.z8 is the binary file that's actually changing). But does git make it easy to go back in time and add new parents to old commits?

I am perfectly willing to "git push -f" and blow away the current history of my Github repository, once I get my local repo looking right. The question is, can I get my local repo looking right?


EDITED YEARS LATER TO ADD: I eventually abandoned my attempts to make the git history of gh-pages look like that; I decided that it was too much work for zero gain. My new practice is to aggressively squash commits to gh-pages, because saving those commit messages really doesn't matter in my case. (It's just a long line of "Bring into line with master commit..."s, none of which are historically interesting.) However, if I needed to do this again, I'd listen to the answers that said

git merge $intended_parent_1 $intended_parent_2
git checkout $original_commit -- .
git commit --amend -a -C $original_commit
like image 698
Quuxplusone Avatar asked May 30 '12 00:05

Quuxplusone


1 Answers

git replace --graft $original_commit \
    $(git show --pretty=%P $original_commit) \
    $additional_parent

Explanation: git replace --graft allows to respecify which are the parents of a given commit. This works by writing a new commit with the respective alterations and writing a replace ref that causes git to look up the new commit instead of the original one whenever it is accessed.

git show --pretty=%P $original_commit just lists the original parents.

like image 149
rumpel Avatar answered Oct 16 '22 10:10

rumpel