0

I have a git repository with a few commits in it. Unfortunately, in truth it is based on a repo from github that has hundreds of commits in it.

I have located the commit on github that our first commit was based on. I added the github repo as another remote using git remote add github $url. I was able to git fetch github master without incident. So I suspect you could diagram my local repository as

can you link it?

except that magenta dotted line leading from A78 to B1 is not part of the commit history. It is the link I want to establish. I want to tell git that the first commit in the non-github upstream is really an altered version of A78 from github (there are definitely diffs between the two, even if they are very very small).

What git command could I issue to establish this magenta genealogical relationship between B1 and A78?

After I perform this command I want to be able to merge all the changes that happened from A78 through B7 onto the head of the A chain (let's call it A147) using a command like git merge github/master so that we have our small patches plus the latest version of the github version (acknowledging that I might have to deal with some merge conflicts).

It is also important that I be able to continue to push changes to our local upstream repository.

answer (since I can't post an answer to a closed question I'll just put it in here)

One of the linked articles mentions the technique of git grafts. I was able to place a graft in .git/info/grafts and that enabled me to merge the changes that happened since the hypothetical A78 into my B branch.

I performed a test of git filter-branch technique but it ended up being a disaster. It caused all the commits to get a new hash and when I pushed this to a test repo and examined the commit graph I observed two complete chains of commits: one with the original hashes, and a second one with the filtered hashes. Needless to say I killed it with fire.

In order to maintain consistency with our local repository and with the github repository: grafts alone are the answer and filter-branch is a very bad idea. Since grafts are per-repository this doesn't completely solve the problem, but if I can figure out how to install a graft in a gitlab repo I think I will declare victory.

Two of the other supposed duplicate questions used git rebase which will rewrite the hashes and cause the history to become incompatible with the preexisting upstream repo.

The concluding sentence of this original question mandated preserving compatibility with the existing upstream repositories. Only a tiny piece of the first supposed duplicate question was safe (the grafts) and the rest would have ruined the commit hashes. The second and third supposed duplicates likewise ruin the commit hashes.

Mutant Bob
  • 1,937
  • 1
  • 16
  • 38
  • You can (almost) only do that by *rewriting* your history, i.e. creating new commits `B1'` to `Bn'` that are incompatible with the original ones that exist now in your repository. Do you really want to do that? – poke Jan 03 '18 at 20:54
  • You could basically do the inverse of what is being discussed [here](https://stackoverflow.com/a/17622991/216074), utilizing `git-replace`. See [Scott Chacon’s blog post](https://git-scm.com/blog/2010/03/17/replace.html) for more information. – poke Jan 03 '18 at 20:59
  • Going along with @poke's comment, IIRC, each commit's hash is combined with its parent's hash. So going back and changing history (e.g. with `git rebase`) to establish this 'link' will change *all* commits on `B`. This may cause issues if any other developers are sharing the same repo. – 0x5453 Jan 03 '18 at 21:12
  • While I don't think this question is exactly a duplicate, some of the threads linked as "answers" did contain useful information. So far I have used grafts to address my problem. The `filter-branch` technique changes the commit hashes, so I suspect it would ruin compatibility with my existing upstream repo. I still have a few more experiments to do before I'm confident in my solution. Even so, I can't post it as an answer on a closed question. – Mutant Bob Jan 08 '18 at 16:16

1 Answers1

1

I think, what you want to do is create a new branch of the repository at the A78 stage.

According to Github guide:

Branching is the way to work on different versions of a repository at one time.

Branching from a repository

For more details look at this Github guide Step 2.

Rushiraj Nenuji
  • 163
  • 2
  • 13
  • If I were starting from scratch this would work, but I already have a shared upstream repository, and branching after the fact does not actually solve the problem. – Mutant Bob Jan 11 '18 at 19:35