0

I have imported another repo as a branch based on solutions here.

Now, the new imported branch is floated while it should be connect the way specified in the image.

How should I do the rebase?

git checkout imported-branch
git rebase ????? --onto ????

git rebase

2
  • What is the relation between f8114a and d0ece ? for example : do you know for a fact that the content of f8114ais exactly the same as the content of d0ece ? Commented Feb 5, 2021 at 14:23
  • @LeGEC, they might be the same or with minimum changes. Commented Feb 5, 2021 at 18:17

1 Answer 1

1

You can't get what you've drawn, because you drew in commit hash IDs: f8114a for instance. Given that f8114a is drawn as a root commit, this means that f8114a is always a root commit, in the past, present, and forever in the future too. But in the right hand side of the drawing, f8114a is not a root commit: it has a parent d0ece. So you've claimed that f8114a is both a root commit (no parents) and a regular everyday commit (one parent, d0ece), and this is simply not possible.

You may be able to get what you want. This depends on precisely what it is that you do want. Trying to do this with git rebase is usually a bad idea, though: if there are any branch-and-merge operations in the set of commits you're trying to graft onto one of your branches, rebase itself will have to re-perform any of the merges involved, and that's a recipe for breaking stuff.

Now, remember that any commit, whatever its hash ID might be, and whatever parent hash IDs it might have, represents a full and complete snapshot of the files that are contained inside that commit. So commit f8114a is a snapshot. Since it it has no parent (on the left side), Git will show it as a comparison against a pseudo-commit that has no files.1 So f8114a consists of add all of its files, when viewed as a set of changes.

If you take f8114a and copy it to a new-and-¿improved? commit—let's call this f9114a, although the actual hash ID will probably be different, but we need to have something to call it2—that does have a parent commit, though, now git show and other Git operations that compare the copy against its parent will have a snapshot to compare against. So now, instead of add all of these files, the diff may say delete most of the files, and create these mostly new ones instead, then change a whole lot of a few remaining files.

If that's OK with you, it's easy to get this to happen in your own repository, without having it happen in any clones anyone makes of your repository. Just use git replace with the --graft option. See the git replace documentation for details.

Once you're satisfied with some replacement(s), you can use a no-op git filter-repo (or the old but still supported, and included with Git distributions, git filter-branch) to rewrite commits reachable from the tip of imported-branch. This will "cement the replacement in place" and allow you to discard the graft; cloning this filtered repository will produce a copy of the filtered repository, which no longer uses the replacement trick.


1Technically Git uses the empty tree to fake up this pseudo-commit. It diffs your commit's tree against the empty tree to produce all the "add entire file" diff-hunks.

2Call it Fred or Barney or Wilma if you like; just don't call it late for dinner.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.