-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
commands: unambiguously resolve remote references #3285
Conversation
We have used the getRemoteRefs since [1] to return a slice of all remote references, without distinguishing which remote they came from. The reason for doing so was that we had had modified each reference's "name" (i.e., the last element of splitting the full reference name by '/'). This was OK to do, since we modified the reference's name (i.e., the last component of the fully qualified reference name as read from Git when splitting on the '/' character) to include the remote name. This allowed us to call '(*git.Ref).Refspec()', which would theoretically format us a correctly printed reference name, for all kinds of references. This is broken in practice, so to prepare for a future commit that will fix it, let's return a map of remote name to all references present on that remote, such that we can format each based on its remote and full name individually. [1]: ce89eb3 (commands/command_migrate: teach how to find all remote refs, 2017-06-09)
Since 5e0f81d (Adding utility methods to get recent refs, 2015-08-17), we have treated references beginning with the prefix "refs/remotes/tags" as being of type "remote tag". This is not a namespace that upstream Git uses in practice to denote remote tags. Instead, tags are automatically namespaced into our local refs/tags, hence rendering this prefix (and its type) meaningless. As such, let's remove it so that the 'git lfs migrate' (et. al.) commands do not get confused about references that do not exist. Co-authored-by: brian m. carlson <[email protected]>
In 'formatRefName()', we special-case references belonging to a remote in order to round-trip a reference name that 'git-rev-parse(1)' (et. al.) will understand. This is done because the `*git.Ref` type does not retain information about the remote to which it belongs, so we add it back here as a shortcut to avoid making this change throughout the codebase. Falling back to ref.Name, however, can introduce ambiguity when there is a top-level reference of the same name. For example, calling 'formatRefName()' on a reference named 'refs/heads/foo' when there is a reference named simply, 'foo' will cause Git to complain. Avoid this by calling `(*git.Ref) Refspec()`, which reintroduces the prefix thus eliminating any ambiguity. Co-authored-by: brian m. carlson <[email protected]>
Since 'formatRefName()' no longer has multiple case statements, let's simplify the body to use an `if`, instead. Co-authored-by: brian m. carlson <[email protected]>
Per our work in the previous commit(s), it is now suitable to call formatRefName() again thus avoiding our "hack" to prepend the remote name to the reference before calling '(*git.Ref) Refspec()'. As such, let's do that. Co-authored-by: brian m. carlson <[email protected]>
Will this fix be in git 2.19.1 do you think? |
This will be in Git LFS 2.6.0, which we don't yet have a release date for, although it will likely be soonish. This is a separate project from Git, although it is bundled in Git for Windows. Git for Windows will likely pick it up automatically once we do the release. I can't say how soon afterwards, though. |
@bk2204 Oops yes I meant the next Git-LFS release sorry. Ok will keep an eye out, tnx! |
I'm on git-lfs 2.6.1 but this still happens:
|
This pull request fixes a long-standing bug wherein a reference beginning with
refs/remotes/tags
would incorrectly be round-tripped back to Git, causinggit lfs migrate
and others to complain of a reference that does not exist.Closes: #3281.
/cc @git-lfs/core
/cc @zezba9000, #3281