简体   繁体   中英

Git fetch notes after forced push on the remote

I am finding a lot of answers to how to make a local branch look like a remote branch, but in my case, I need to take in changes that were force pushed to the remote to refs/notes/commits .

The changes were made using git notes add . The remote was updated using git push origin refs/notes/* -f .

I have different history for refs/notes/commits locally. Until now I was using git fetch origin "refs/notes/*:refs/notes/*" to integrate remote notes changes to my local. With the forced push, the two histories are now disjoint. I want to throw away mine and take in theirs.

Since refs/notes/commits is not a branch (right?) I cannot use git push or git checkout to enter it and then git reset (again, right?). So, what can I use to make my local refs/notes* equivalent to the remote refs/notes/* ?

It's true that refs/notes/commits is not a branch , as all branch names by definition start with refs/heads/ instead. However, git fetch and git push work with any ref-name, and you can force-fetch as well as force-push. So:

Until now I was using git fetch origin "refs/notes/*:refs/notes/*" to integrate remote notes changes to my local. With the forced push, the two histories are now disjoint. I want to throw away mine and take in theirs.

That would be a forced fetch. To force a fetch, do the same thing you do with git push : add the --force flag, or prefix the refspec —the pair of names separated by a colon—with a plus sign. The latter is shorter (by at least one character) so that's the one I'll use here: 1

git fetch origin "+refs/notes/*:refs/notes/*"

or:

git fetch origin "+refs/notes/commits:refs/notes/commits"

This will overwrite the current value (stored hash ID) of your refs/notes/commits with the fetched value, provided they have a refs/notes/commits ; the variant with * will overwrite all of your refs/notes/ names with theirs (creating any names they have that you didn't before).


1 Note that + in front of a refspec sets the force flag for that one refspec , while --force on the command line sets the force flag for all refspecs. That is:

git fetch origin refs/heads/br1:refs/heads/br1 +refs/heads/br2:refs/heads/br2

fetches from origin's branch br1 to (local) branch br1 without forcing, but fetches from origin's br2 to br2 with forcing. Compare with:

git fetch --force origin refs/heads/br1:refs/heads/br1 refs/heads/br2:refs/heads/br2

which forces both updates. A forced update simply takes place even if Git's normal rules would reject the update. 2

2 For git push , the other end can add additional, non-Git rules . That's how GitHub and others provide "protected branches", for instance. Since these are not Git's normal rules, the --force or + flag does not override these rules. There's nothing equivalent for git fetch , since that's into your own repository and you are assumed to know what you are doing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM