1

given the following git log, how do i add a file (which never existed in any commit) to commit B, so that this new file will appear in every other commit that A?

A --> B -----> D ------> F
       \--> C --> E --/

In my attempts with git rebase --onto i did not succeed in not having to essentially duplicate every commit amending the contents but i am sure i am not approaching it using the full power of git. Any help?

Note: remote is fine to be forced, or even deleted and pushed again, that's not a worry.

Thanks a lot

Gianks
  • 63
  • 1
  • 15

2 Answers2

1

The end result will be that : duplicating all the commits.

About the ways to do it, though, you can use git rebase with some options :

# -i for --interactive
# -r for --rebase-merges
git rebase -i -r A

git will open a text editor for you, asking you to describe what actions you want to take on each commit.

In that file :

  • find the line mentioning commit B
  • change the action from pick to edit
  • save and exit

git will start applying the script you instructed him to, and will pause after reaching B.

At this point, you can add the extra file :

  • git add the file you want
  • git commit --amend to add it to B
  • git rebase --continue to proceed with the rebase

This should rewrite all the commits after B.

You can check your local history, and the content of your commits,
if you are satisfied with the result you can push --force.

LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • Hi, i just tried and i think this could be a solution even if following your steps i ended up with a sort of split history. A is the ancestor of B and B', where B is still parent of D and B' is a new parent of C. Any idea why? It seems the edit of B has not affected the C-E branch. Interestingly F, the original merge-back commit seems to be gone. – Gianks Dec 14 '20 at 13:22
  • Mission Accomplished. Please edit your answer and add --preserver-merges (deprecated, but the one i used) or, even better, --rebase-merges to the rebase command. This will preserve the merges and will not flat down the tree! – Gianks Dec 14 '20 at 14:23
  • Done. I had mixed my options up, fixed. – LeGEC Dec 14 '20 at 14:33
1

git filter-branch could be of help. It can rewrite a range of commits at once. From your note I take that you are aware of the potential problems wrt. commit rewriting of shared history (different hashes, etc.)

NB. It can't hurt to create a backup copy before trying this :)

git filter-branch \
  --index-filter 'cp /path/to/new/file path/in/repo && git add path/in/repo/file' \
  -- A..F

This applies the filter to all commits reachable from F, but excluding any commits reachable from A (in other words: excluding A and all ancestors of it)

knittl
  • 246,190
  • 53
  • 318
  • 364
  • Hi, thanks for the suggestion. Looking into the docs filter-branch seems to be a potential nightmare and causes, in any event, the presence of extra unwanted entities in the rewritten repo. Anyway you inspired me to look into https://github.com/newren/git-filter-repo as the doc suggests and i will give it a try today! – Gianks Dec 14 '20 at 10:21