0

I'm keeping my changelog in git-notes --ref changelog when developing. I'm always putting a note on the merge-to-master commit and push it out to three remotes (git push <remote> refs/notes/changelog) - but every time I forget to push to one remote and fetch from it, the ref gets overridden with some old version:

(Sorry for german locale)

$ git fetch github -p
Von github.com:<user>/<repo>
 + ca36d98d...1f3b9041 refs/notes/changelog -> refs/notes/changelog  (Aktualisierung erzwungen)

How to prevent that? Is it somehow related to my .git/config?

(excerpt from .git/config):

[remote "github"]
    url = git@github.com:<user>/<repo>.git
    fetch = +refs/heads/*:refs/remotes/github/*
    fetch = +refs/pull/*/head:refs/remotes/github/pr/*
    push = +refs/notes/changelog:refs/notes/changelog
    fetch = +refs/notes/changelog:refs/notes/changelog
[notes "rewrite"]
    rebase = true
    amend = true
[notes]
    rewriteRef = refs/notes/changelog
musicmatze
  • 4,124
  • 7
  • 33
  • 48
  • It seems that the `+` in the `fetch = ` and `push = ` specs in my `.git/config` allows non-fast-forward pushes of these refs. I'm removing this `+` now and time will tell whether this was the issue. – musicmatze Apr 24 '18 at 16:33

1 Answers1

3

You are correct. Each fetch line in your .git/config file specifies one of however-many default fetch refspecs Git will use, so:

fetch = +refs/heads/*:refs/remotes/github/*
fetch = +refs/pull/*/head:refs/remotes/github/pr/*
fetch = +refs/notes/changelog:refs/notes/changelog

provides three such refspecs.

Each refspec consists of two main parts separated by a colon: on the left there is the source reference and on the right there is the destination reference. Asterisks * may be used and act mostly like shell glob * (as a source only; the destination * is replaced with whatever the source * matched). If this pair is prefixed with a plus sign +, the update is always forced (as if you used --force on the command line).

Note that remote-tracking names such as refs/remotes/github/master exist in a per-remote space: you will fetch origin's master into refs/remotes/origin/master which is clearly different from refs/remotes/github/master. Hence it's safe, at least for all ordinary purposes, to fetch with force for such names: you cannot overwrite your own branches, which are in refs/heads/, nor any other remote's remote-tracking names.

This is of course not true for notes references in refs/notes/, nor for tags in refs/tags/, so use care with leading + on either of those.

torek
  • 448,244
  • 59
  • 642
  • 775