Skip to content
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

Merged
merged 5 commits into from
Sep 26, 2018

Conversation

ttaylorr
Copy link
Contributor

This pull request fixes a long-standing bug wherein a reference beginning with refs/remotes/tags would incorrectly be round-tripped back to Git, causing git lfs migrate and others to complain of a reference that does not exist.

Closes: #3281.

/cc @git-lfs/core
/cc @zezba9000, #3281

ttaylorr and others added 5 commits September 24, 2018 20:47
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]>
@ttaylorr ttaylorr added this to the v2.6.0 milestone Sep 25, 2018
@ttaylorr ttaylorr requested a review from a team September 25, 2018 21:45
@zezba9000
Copy link

zezba9000 commented Sep 26, 2018

Will this fix be in git 2.19.1 do you think?

@bk2204
Copy link
Member

bk2204 commented Sep 26, 2018

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.

@zezba9000
Copy link

@bk2204 Oops yes I meant the next Git-LFS release sorry. Ok will keep an eye out, tnx!

@ttaylorr ttaylorr merged commit 48a931c into master Sep 26, 2018
@ttaylorr ttaylorr deleted the ttaylorr/remote-tags branch September 26, 2018 18:16
@bk2204 bk2204 mentioned this pull request Oct 2, 2018
@hybridherbst
Copy link

hybridherbst commented Sep 12, 2019

I'm on git-lfs 2.6.1 but this still happens:

herbst@PFC MINGW32 /e/git/project (master)
$ git lfs migrate import --fixup
migrate: Fetching remote refs: ..., done
Error in git rev-list --stdin --reverse --topo-order --do-walk --: exit status 1
28 fatal: bad revision '^refs/remotes/origin/Alpha-0.5'
migrate: Sorting commits: ..., done

$ git lfs version
git-lfs/2.6.1 (GitHub; windows 386; go 1.11.1; git dc072c3e)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

git lfs migrate import (Error in git)
4 participants