Page MenuHomePhabricator

Branch names are not correct in Drydock working copies
Closed, ResolvedPublic

Description

Steps to reproduce:

  1. Create a repository with multiple branches
  2. Build a commit at the HEAD of a non-master branch
  3. Run git show-ref --heads

Issue:
We have a tool that runs as part of our build which resolves the current commit using git rev-parse HEAD and then uses git show-ref --heads to determine the current branch. When run on a Drydock working copy, it always returns master even when the result should be something else.

Event Timeline

epriestley claimed this task.
epriestley added a subscriber: epriestley.

There is no such thing as a "current branch" in this sense in the general case. Harbormaster builds commits, and a commit may be on anything between zero and infinity branches, and may be the head of any equal or smaller number of branches.

You may be able to use git branch --contains HEAD instead.

I'm not actually after a "current branch"; I know that there's potentially unlimited branches for the current commit. What I'm interested in is actually having the branches from the remote fetched down as the local branch names, so that "master" locally is the same as "origin/master" and "abcdef" is the same as "origin/abcdef", or to put it another way, as if the repository had been freshly cloned with "git clone".

That would needlessly slow down working copy construction in the common case, by adding extra unnecessary steps. Have your build tools examine remote branches instead of local branches, or do this synchronization yourself at the beginning of your build, or wait for T9492 and use "one-time" working copies in exchange for inefficient working copy construction.

You don't need to examine the remote branches beyond git fetch, which I'm assuming has already been done when the working copy is fetched. You just need to map the local branches to the remote ones (you can actually just do this cp .git/refs/remotes/origin/* .git/refs/heads).

However, if you intentionally don't want branches to be available in the working copy, it's probably better to just remove all of the branches from the working copy and checking out a detached HEAD rather than resetting the master branch to the commit, because having master point at abcdef when the two branches don't even share any common commits in the remote is very confusing.

That's entirely reasonable, but completely unclear from the task title, reproduction steps, description, or other context here. Here's an example of how you could have filed this task instead to make the root issue more clear:


Drydock working copies move unrelated "master" branch pointer to current commit

When Drydock constructs a working copy at some commit, it resets whatever branch it is on to that commit. This may lead to commits appearing on branches locally when they do not appear on those branches in the remote.

Reproduction steps:

  • Create a repository with multiple branches
  • Build a commit that does not appear on master
  • Examine local branches with git show-ref --heads

Expected results:

  • master does not point at the commit being built.

Actual results:

  • master incorrectly points at the commit, even though the commit does not appear on master in the remote.

This is because Drydock uses git reset --hard <commit>, which also resets the current branch pointer.

A better behavior might be to check out the commit first in a detached HEAD (git checkout <commit>), then reset the working copy to it.

Right, but that's because to me master being incorrect is a symptom of all branches being incorrect, which is what the task title and reproduction steps demonstrate.