2

I have a repo I inherited, it was created by downloading a zip of code from github not cloned, and almost all changes were made before the first commit.

I found which commit it was created at (I think) and after cloning the github repo I made a branch off that commit. I also added the incomplete repo as a remote to the complete repo cloned from github.

Now I'd like to take the commits from the incomplete repo and rebase? them onto the branch in the complete repo, preferably while maintaining previous ownership of the commits.

1 Answer 1

2
  1. First temporarily "graft" two histories together via .git/info/grafts. This adds fake parents to any given commit. The syntax is:

    commit-id parent-id [parent-id...]
    

    Let's say your oldest commit is 1234567890, and you think it was based on GitHub repo's commit abcdefghijkl. With that, your .git/info/grafts file should look like:

    1234567890 abcdefghijkl
    

    Note that you must use the full 20-character commit IDs, not the shortened ones.

    (The same can also be achieved using "replaced objects" and git replace --graft. The mechanism is different, but the end result is the same.)

  2. Use git log --stat --decorate to make sure you got it right. You should see a "(grafted)" decoration next to 1234567890.

  3. Finally, run git filter-branch abcdefghijkl..HEAD to "bake in" the graft and make it permanent. After this, the log should look identical, but "(grafted)" marker should have disappeared. You can delete .git/info/grafts as well.

    Note that this will change all commit IDs up to (and including) the grafted commit.

4
  • So just out of curiosity how will git handle files that it thinks were added in the oldest commit, but in fact were only modified from the commit it was based on. The were unfortunately added already modified in the "initial" commit. Nov 25, 2015 at 21:58
  • 1
    @CamdenNarzt: In Git, commits are snapshots, not changesets – they do not have "file X added" or "file Y changed"; they only have "at this point in time, there were files X Y Z and they looked like this". Diffs are computed by comparing against the parent commit. So that means nothing special needs to be done – once you graft a parent onto the "initial" commit, Git will only care about how the two commits' contents differ, and file changes & additions will show up naturally. Nov 26, 2015 at 5:42
  • Sorry for taking so long to accept this, the first time I tried this process I must have made some mistake, as it didn't work. I've retried the process successfully now. Oct 3, 2016 at 23:38
  • Instead of filter-branch, use git-filter-repo. This is an external tool which will do the same thing more safely and reliably. It works on the commit contents itself, instead of manipulating the working tree, making it faster too.
    – Nick ODell
    Oct 30, 2020 at 23:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .