Bug 2920 - attempt to create an existing branch in a git subrepo
Summary: attempt to create an existing branch in a git subrepo
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: Mercurial (show other bugs)
Version: unspecified
Hardware: All All
: normal bug
Assignee: Bugzilla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-07-22 15:22 UTC by ben hockey
Modified: 2012-05-13 04:56 UTC (History)
6 users (show)

See Also:
Python Version: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description ben hockey 2011-07-22 15:22 UTC
i have a situation where mercurial fails to properly update a git subrepo.

it seems that at some point a branch called 'origin/master' is mistakenly 
created - the 'master' branch existed and should have been used.  after 
this, when i try to hg pull --update i get an error because another attempt 
is made to create the 'origin/master' branch again.  

i haven't yet been able to pinpoint the exact conditions that cause this but 
below is some of the debug output for a failed command:

static/cws2/external/twine: git config 
branch.refs/heads/origin/master.remote
static/cws2/external/twine: git config branch.refs/heads/master.remote
static/cws2/external/twine: git checkout -b origin/master 
refs/remotes/origin/master
fatal: git checkout: branch origin/master already exists
abort: git checkout error 128 in static/cws2/external/twine

the first call to git config should be like this

git config branch.master.remote

it seems that there is some mismatch with string substitution using branch 
names, refs, etc.  i'm not sure if i have found the root cause but the line 
that results in the wrong call to config is 
http://selenic.com/repo/hg/file/96a72cbc6c29/mercurial/subrepo.py#l812 - its 
using the ref instead of the branch name.
Comment 1 ben hockey 2011-08-12 11:51 UTC
it looks like the fix for this should be simple.

using http://selenic.com/repo/hg/file/c981f4a9ea74/mercurial/subrepo.py for 
line number references.

_gitbranchmap generates and returns branch2rev and rev2branch (line 803).  the 
keys of branch2rev are based on the result of the call to git for-each-ref 
(line 792).  these keys are of the form refs/heads/<branch> or 
refs/remotes/<remote>/<branch>

the keys of branch2rev are passed to _gittracking (line 912).  _gittracking 
iterates over the keys and ignores any that start with refs/remotes (line 810).  
for the rest of the keys, they are substituted into a call to git config in 
order to determine their corresponding remote (line 812).  this line is where 
the error is.  at that point the value of b that is substituted looks like 
refs/heads/<branch>.  the correct value of b is just <branch>.  ie, b needs to 
be everything after refs/heads/

my python skills are very basic so i'm hoping that someone can see the problem 
based on my description and produce a patch.
Comment 2 ben hockey 2011-08-19 15:00 UTC
good news... i've got the steps to reproduce this error.  this was done on 
FreeBSD 8.2 with git 1.7.5.4 and mercurial 1.9.1 installed from the ports tree 
(but most of that shouldn't matter).  the steps below are not my workflow, 
they were just contrived in order to reveal this bug.

# initialize a git repository
git init gitrepo
cd gitrepo
touch a
git add .
git commit -m "initialized repo"

# create a new branch in the git repo and make some changes
git checkout -b develop
touch b
git add .
git commit -m "doing some development"

# initialize a mercurial repository and include the git subrepo develop branch
cd ..
hg init remote
cd remote
echo 'gitrepo = [git]../gitrepo' > .hgsub
hg add .hgsub
git clone ../gitrepo -b develop
hg commit -m "initialized with gitrepo (develop)"

# clone the remote repo into a local repo
cd ..
hg clone remote local

# do some more development in the gitrepo
cd gitrepo
touch c
git add .
git commit -m "more development"

# update the remote mercurial repo
cd ../remote/gitrepo
git pull
cd ..
hg commit -m "update gitrepo"

# pull the remote changes into the local mercurial repo
cd ../local
hg pull
hg update --debug # switches to branch origin/develop - this is not right

# confirm we have a bad branch
cd gitrepo
git branch # lists origin/develop as a branch

# do some more development in the git repo
cd ../../gitrepo
touch d
git add .
git commit -m "another update"

# pull the git changes into the mercurial remote repo
cd ../remote/gitrepo
git pull
cd ..
hg commit -m "about to break local"

# update the local mercurial repo and break it
cd ../local
hg pull
hg update --debug # this will now break it
Comment 3 HG Bot 2011-10-12 16:00 UTC
Fixed by http://selenic.com/repo/hg/rev/5d700b7edd85
Eric Roshan Eisner <ede@alum.mit.edu>
subrepo: fix git branch tracking logic (issue2920)

(please test the fix)
Comment 4 Bugzilla 2012-05-12 09:22 UTC

--- Bug imported by bugzilla@serpentine.com 2012-05-12 09:22 EDT  ---

This bug was previously known as _bug_ 2920 at http://mercurial.selenic.com/bts/issue2920