comment
This commit is contained in:
parent
b68a319dab
commit
eed66c0164
1 changed files with 78 additions and 0 deletions
|
@ -0,0 +1,78 @@
|
|||
[[!comment format=mdwn
|
||||
username="joey"
|
||||
subject="""comment 1"""
|
||||
date="2024-02-09T20:01:01Z"
|
||||
content="""
|
||||
Well `git replace` does turn out to be able to do this. With some caveats.
|
||||
|
||||
I started with this history:
|
||||
|
||||
6df78e79d688de8392d952dc8705d094384ed2c0 add file (accidentially to git)
|
||||
3235872149f1767efd282635ca12ec2f9056f9cc initial commit
|
||||
|
||||
Then amended 6df78e, following the usual
|
||||
process to convert git to annexed, as outlined in [[tips/largefiles]],
|
||||
producing commit f36b42e.
|
||||
|
||||
Then `git replace 6df78e f36b42e` and the log changed to:
|
||||
|
||||
6df78e79d688de8392d952dc8705d094384ed2c0 (replaced) add file (to annex)
|
||||
3235872149f1767efd282635ca12ec2f9056f9cc initial commit
|
||||
|
||||
Note that, when there are further commits made on top of
|
||||
the bad commit, they all would need to be replaced with amended commits
|
||||
as well.
|
||||
|
||||
I'd already pushed to origin before this. And origin still showed the bad
|
||||
commit in its log. But pushing the replace refs fixed that:
|
||||
|
||||
git push origin 'refs/replace/*'
|
||||
|
||||
Now looking at the origin repo showed the same amended history.
|
||||
|
||||
In another clone, the old history is still visible, but that can be fixed, by running:
|
||||
|
||||
git fetch origin 'refs/replace/*:refs/replace/*'
|
||||
|
||||
Then I deleted the git object for 6df78e from the origin repo, along with the
|
||||
blob object that contained the content of the file accidentially added to git.
|
||||
|
||||
This is where it fell down, because cloning from that origin repo then
|
||||
fails:
|
||||
|
||||
joey@darkstar:~/tmp/test>git clone demo.git/ democlone
|
||||
Cloning into 'democlone'...
|
||||
done.
|
||||
fatal: update_ref failed for ref 'HEAD': cannot update ref 'refs/heads/master': trying to write ref 'refs/heads/master' with nonexistent object 6df78e79d688de8392d952dc8705d094384ed2c0
|
||||
|
||||
But, that can be worked around. Just need to make an additional commit on top of the
|
||||
replaced commit, so git clone will see a commit that has not been deleted. I did that,
|
||||
and:
|
||||
|
||||
joey@darkstar:~/tmp/test>git clone demo.git/ democlone
|
||||
Cloning into 'democlone'...
|
||||
done.
|
||||
joey@darkstar:~/tmp/test>cd democlone
|
||||
joey@darkstar:~/tmp/test/democlone>git log
|
||||
error: Could not read 6df78e79d688de8392d952dc8705d094384ed2c0
|
||||
fatal: Failed to traverse parents of commit 167b6e6842a669bc90925dd4b6df0c1a6ec4c141
|
||||
|
||||
joey@darkstar:~/tmp/test/democlone>git fetch origin 'refs/replace/*:refs/replace/*'
|
||||
From /home/joey/tmp/test/demo
|
||||
* [new ref] refs/replace/6df78e79d688de8392d952dc8705d094384ed2c0 -> refs/replace/6df78e79d688de8392d952dc8705d094384ed2c0
|
||||
joey@darkstar:~/tmp/test/democlone>git log --pretty=oneline
|
||||
167b6e6842a669bc90925dd4b6df0c1a6ec4c141 (HEAD -> master, origin/master, origin/HEAD) empty
|
||||
6df78e79d688de8392d952dc8705d094384ed2c0 (replaced) add file (to annex)
|
||||
3235872149f1767efd282635ca12ec2f9056f9cc initial commit
|
||||
|
||||
So, you can do this if you're ok with clones needing to manually fetch the replace refs
|
||||
in order to access the replaced history.
|
||||
|
||||
And of course, existing clones need to be manually updated to fetch the replace refs.
|
||||
And probably ought to have the bad objects deleted out of their .git/objects/
|
||||
to avoid accidental data leakage.
|
||||
|
||||
I'd also caution that, if the history you rewrite with `git replace` contains a lot
|
||||
of commits, the number of refs in refs/replace/* could get large, and a large number
|
||||
of git refs can be innefficient in various ways.
|
||||
"""]]
|
Loading…
Add table
Add a link
Reference in a new issue