Lets say git repository's master
branch is currently tagged v4.0
.
At some point (years ago) someone grabbed a clone of a v2.0
tag and made a bunch of changes to it, but didn't maintain his own branch or even kept his code under git.
To make things even worse the biggest problem is that he had grabbed a commit off a branch that was actually a child of this v2.0
tag, and that branch is now gone (must've been a rebase, not 100% sure). So I don't really have the exact common ancestor.
A diff between the untracked code against v2.0
can be applied almost (w/some Fuzz) cleanly up to a certain point in the current commit history (around our v2.7
tag), however after v3.0
major stuff changed (directories moved, files renamed, etc) and that diff obviously stops working there.
So a branch can be created off of anything v2.0..v2.7
in the current repository to try and keep the old code somehow tracked.
What would be the correct way of properly merging this untracked code into a branch that is closer to master
?
I've never had to rebase anything, but if my understanding of the concept is correct, I would be effectively pushing the master
's branch commits into my new branch where I applied the diff (against the v2.0
era), which I can then attempt to merge back into the master
branch afterwards.
My flow/process just never succeeds, when the v2.8..v3.0
commits start to pop up the conflicts become pretty unmanageable, it's as if commits were grabbed after the original clone (some patches fail because they seem already applied) and it's making a mess of everything (or perhaps, as I've mentioned, my original choice for a common ancestor is just wrong).
If finding the correct/closest common ancestor is paramount, is there a git way to do such a thing? All I can think of is making a script that would count diff lines between the old code against each commit in a range and return the one commit that produces the smallest diff.
Are there proper procedures/methods/tools/alternatives for merging branched-out, untracked, old code into a recent~ish branch in git?.
I've never had to rebase anything, but if my understanding of the concept is correct, I would be effectively pushing the master's branch commits into my new branch where I applied the diff (against the v2.0 era), which I can then attempt to merge back into the master branch afterwards.
No: a git checkout oldBranch; git rebase master
would replay the commits from oldBranch
on top of master
.
Then, a merge back to master
would be a trivial fast-forward merge.
But a rebase is not a practical solution here (too many commits to replay, too many conflicts)
Are there proper procedures/methods/tools/alternatives for merging branched-out, untracked, old code into a recent~ish branch in git?.
A merge (merge master
into your old branch) is preferable to replay lots of old commits (which would introduce conflicts for each commit replayed).
In that merge (first from master
to your branch), you would solve those conflicts once (to create a stable merge commit), in isolation in your old branch.
That won't be easy (there is no miracle solution to render an old code compatible with a more recent one), but at least you are dealing with one commit (a merge commit) to fix.
Once you are satisfied that your merge is working, you can merge back to master
.
Note: on the fuzz
term:
"git rebase --help
"(man) referred to offset
(the difference between the location a change was taken from and the change gets replaced) incorrectly and called it "fuzz
", which has been corrected with Git 2.47 (Q4 2024), batch 2.
See commit 70058db (25 Jul 2024) by Junio C Hamano (gitster
).
(Merged by Junio C Hamano -- gitster
-- in commit 5617a8e, 01 Aug 2024)
doc
: difference in location to apply is "offset
", not "fuzz
":
The documentation to "
git rebase
"(man) says that the line numbers (in the rebased change) may not exactly be the same as the line numbers the change gets replayed on top of the new base, but uses a wrong noun "fuzz
".
It should have said "offset
".They are both terms of art.
- "
fuzz
" is about context lines not exactly matching.- "
offset
" is about the difference in the location that a change was taken from the original and the change gets replayed on the target.So:
- "
offset
" is often inevitable and part of normal life.- "
fuzz
" on the other hand is often a sign of trouble (and indeed "Git" refuses to apply a change with "fuzz
", except there are options to be fuzzy about whitespaces).
git rebase
now includes in its man page:
line numbers have to be taken with some offset, since the other side