Is there a way to "unfetch" notes?

Viewed 48

Context:

We are using gerrit, and I missed to add a topic for a few gerrit changesets.

One person suggested to do a git fetch origin "refs/notes/*:refs/notes/*", then "edit" the review notes and push back the outcome of that. Turns out: our permissions are setup so that I can fetch notes, but not push them. But the person who has the authority to push such changes fixed the entries that needed fixing, so I am all fine regarding that aspect.

Out of curiosity, I did git fetch origin "refs/notes/*:refs/notes/*" again today, and I get

remote: Counting objects: 333792, done
...
Resolving deltas: 100% (103/103), completed with 44 local objects.
From ssh://whatever....
 ! [rejected]                refs/notes/review -> refs/notes/review  (non-fast-forward)

This is like the first time I fetched "notes", and I guess: I really don't need that information locally.

Thus:

  • Is there a way to "remove" that fetched content?
  • If not, how can I force my local repository to forget about the changes I made locally to "notes"?
1 Answers

You can:

  • delete your refs/notes/review reference entirely;
  • leave it as is (there's probably no reason to do this); or
  • force-update your own refs/notes/review from their refs/notes/review so as to always have the latest ones.

Deleting your notes

The first of these achieves your first bullet point. To do this, simply run:

git update-ref -d refs/notes/review

Updating your notes

The last one achieves your second bullet point. To do this one time, run:

git fetch origin +refs/notes/review:refs/notes/review

or:

git fetch --force origin refs/notes/review:refs/notes/review

which is what you did the first time, except with the "force" flag set, telling your own Git to update yours from theirs, even if this loses work you did locally.

To do this on every git fetch origin, you can do one of several things. My preferred method is to open .git/config in my editor (git config --edit will do this). You will find, in this config file, some lines of this form:

[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*

(There will also be a url setting.)

This fetch line tells your Git: Every time I connect to origin, by default, I want you, my Git, to take all of their refs/heads/* names—all their branch names—and use those to force-update my own refs/remotes/origin/* names. This is how your remote-tracking names work.

Adding a second fetch = line:

        fetch = +refs/notes/review:refs/notes/review

tells your Git: Then, having updated my refs/remotes/origin/* from their refs/heads/*, also force-update my refs/notes/review from their refs/notes/review.

You can have as many fetch lines as you like. You can use these to implement fancy tricks, such as bringing over other notes and renaming them, for instance.

Related