Re: Bug Report: notes disassociated after history edits

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Aug 22, 2019 at 04:44:37PM -0400, Christopher Sean Morrison wrote:

> We’re migrating a very large old repository to Git (the oldest in
> continuous development!) and using the notes feature to preserve Svn
> data like revision IDs and branch information.  We’ve run into what
> seems like an incomplete feature or bug in that notes get
> orphaned/disassociated if an old commit is changed (e.g., edit a
> committer's e-mail or the commit message).
> 
> The changed commit and all children commits get sha updates, but the
> notes remain associated with the original sha.  This can be
> particularly catastrophic, for example, if an early commit is changed
> as all notes become orphaned.
> 
> I presume this is a bug but perhaps we may be doing something wrong?
> Is there a better way to preserve old Svn information that will work
> with filter-branch?

Whether the old notes apply to the rewritten commit depends on what is
in the notes. Commands like rebase and "commit --amend" that rewrite
history have some options to carry notes across rewrites. See
"notes.rewrite*" in "git help config".

I don't think that filter-branch ever learned about rewriting notes.
Here's an old thread asking the same thing:

  https://public-inbox.org/git/hbf.20110317iwua@xxxxxxxxxxxxx/

And it even mentions an even more ancient patch:

  https://public-inbox.org/git/0ad4b8c1a5377d697513cd8e49f64419cd8deef4.1266164150.git.trast@xxxxxxxxxxxxxxx/

The consensus seems to be that filter-branch should actually have a
notes filter, but nobody ever implemented it.

In the meantime, I think you could accomplish the same thing with a
--commit-filter. This seems to work for me:

  # fake repo with some notes
  git init repo
  cd repo
  for i in 1 2 3; do
	echo $i >orig-$i
	git add orig-$i
	git commit -m $i
	git notes add -m "note $i"
  done

  # introduce a silly tree change that will modify the commit ids,
  # and map the notes, too
  git filter-branch \
	  --tree-filter 'rename s/orig-/new-/ *' \
	  --commit-filter '
		commit=$(git commit-tree "$@")
		git notes copy $GIT_COMMIT $commit
		echo $commit
	  '

  # this should have the new-* files, but still have notes
  git log --raw

I think you could also use "--state-branch", and then pass its mapping
into a single "notes copy" invocation, which would be much more
efficient. E.g.:

  git filter-branch \
    --tree-filter 'rename s/orig-/new-/ *' \
    --state-branch refs/mapped-state
  git cat-file blob refs/mapped-state:filter.map |
    tr ':' ' ' |
    git notes copy --stdin

Hope that helps.

-Peff



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux