GNOME Bugzilla – Bug 549704
Failure when updating a git branch
Last modified: 2009-04-24 14:18:54 UTC
The initial checkout works fine *** Checking out sugar-toolkit *** [1/1] git clone git://dev.laptop.org/sugar-toolkit Initialized empty Git repository in /home/marco/sugar-jhbuild-0.82/source/sugar-toolkit/.git/ remote: Generating pack... remote: Done counting 26861 objects. remote: Deltifying 26861 objects... remote: 100% (26861/26861) done remote: Total 26861 (delta 20062), reused 25403 (delta 19075) Receiving objects: 100% (26861/26861), 3.95 MiB | 361 KiB/s, done. Resolving deltas: 100% (20062/20062), done. git show-branch sucrose-0.82 fatal: bad sha1 reference sucrose-0.82 git checkout -b sucrose-0.82 origin/sucrose-0.82 Branch sucrose-0.82 set up to track remote branch refs/remotes/origin/sucrose-0.82. Switched to a new branch "sucrose-0.82" *** success *** [1/1] But then when I try to updateone the module, it fails: [marco@localhost sugar-jhbuild-0.82]$ ./sugar-jhbuild updateone sugar-toolkit *** Checking out sugar-toolkit *** [1/1] git fetch git stash save jhbuild-build No local changes to save git checkout sucrose-0.82 Already on "sucrose-0.82" git rebase origin sucrose-0.82 Already on "sucrose-0.82" First, rewinding head to replay your work on top of it... HEAD is now at 9f88241 Merge branch 'master' of git+ssh://dev.laptop.org/git/sugar-toolkit Applying Fix gettext invocation, and set text domain (fixes #7800) error: patch failed: src/sugar/util.py:21 error: src/sugar/util.py: patch does not apply Using index info to reconstruct a base tree... Falling back to patching base and 3-way merge... Auto-merged src/sugar/util.py CONFLICT (content): Merge conflict in src/sugar/util.py Failed to merge in the changes. Patch failed at 0001. Not a git expert but shouldn't we be doing something like this: diff --git a/jhbuild/versioncontrol/git.py b/jhbuild/versioncontrol/git.py index ad3283b..8274076 100644 --- a/jhbuild/versioncontrol/git.py +++ b/jhbuild/versioncontrol/git.py @@ -205,7 +205,7 @@ class GitBranch(Branch): if not self.tag: if self.branch: - buildscript.execute(['git', 'rebase', 'origin', self.branch], 'git', cwd=cwd) + buildscript.execute(['git', 'rebase', 'origin/' + self.branch, self.branch], 'git', cwd=cwd) else: buildscript.execute(['git', 'rebase', 'origin', 'master'], 'git', cwd=cwd)
Created attachment 117522 [details] [review] Possible fix
hi I don't think 'origin/' + self.branch is correct, because you might well have self.branch totally different than the origin name. I don't know what should be the correct command to rebase on top of the tracked branch.. but your patch is probably not valid
I recently encountered this bug as well. Anyone have any ideas on the right way to proceed? I'm not a git or jhbuild expert either, but for our case, I believe we want to git-pull on the branch. This is run as a buildbot build step, so there shouldn't be any local modifications in the repository, and git-stash should clean out the index. I realize this might not work for the common case. Thoughts? brian
I guess it could be fixed when the git workflow will be made configurable, as proposed in bug 552476; don't hesitate to add your comments over there.
When I landed my dvcs integration stuff I also landed a patch for this that uses GitBranch.branchname to figure out which branch to rebase against. (origin/$branch doesnt work with git-mirror.gnome.org...) This makes the assumption that jhbuild checked out the repository and so knows what the upstream branch/tag/commit/ref is. elmarco, i'm not entirely sure i follow the situation you mention. I think it still occurs with my change though? From poking my git clone of jhbuild (and current svn jhbuild as of today). I create a branch called badger based off the jhbuild-ng branch. git checkout -b badger origin/svn/jhbuild-ng If i use jhbuild now it will checkout whatever branch is specified in moduleset. If no branch is specified, it will just git checkout with no branch specified. If no tag is specified, it will try and rebase my local changes on top of something. If branch is specified, it will figure out something via branchname(), otherwise it defaults to origin. For our example, it would have probably still gone: git checkout git rebase origin master I think that means that i'm now back on master, instead of the badger branch. I think in most cases the correct behaviour is to rebase on top of the branch we track. For our badger branch we would want to git rebase origin/svn/jhbuild-ng (Don't need to checkout or specify a branch - git will use the one we are currently on). So we just need git commands to find origin/svn/jhbuild-ng for the current branch. The best i have is to do some string foo on the output of: git config --get branch.badger.remote git config --get branch.badger.merge Thoughts?
From #git: 16:10 < Jc2k> is there a command that will tell me which remote branch my current local branch would merge from if i git pull? e.g. origin/master, origin/foo, origin/svn/spacemonkey etc 16:11 < jast> Jc2k, git remote show foo gives a lot of information. i think there are other ways, too. 16:13 < Jc2k> jast: git remote show gives me origin... im looking for the ref too.. 16:13 < doener> Jc2k: git remote show <remote> 16:13 < jast> remote show displays branch tracking information too 16:14 < Jc2k> ah, i have to specify origin to get the branch tracking info 16:15 < Jc2k> hmm 16:15 < Jc2k> anything scriptable? 16:15 < doener> Jc2k: git config --get branch.<name>.{remote,merge} 16:16 < Jc2k> doener: that was what i had.. was hoping for a one liner.. 16:16 < Jc2k> doener: will merge always start with refs/heads/? 16:17 < jast> in practice, yes 16:17 < doener> Jc2k: you could probably also have refs/tags/v1.6.0 there, but that's kinda pointless 16:18 < doener> Jc2k: some git-svn users might have refs/remotes/foobar there, though such a setup would be kind of suicidal ;-) 16:20 < doener> Jc2k: the merge config value doesn't necessarily correspond to any remote tracking branch. That's just how the defaults work. 16:20 < doener> Jc2k: for a given remote, you could have a fetch line that only fetches branch1 and branch2, but still have a branch setup to fetch and merge branch3, although you don't even have a remote tracking branch for it 16:21 * Jc2k goes blind 16:21 < Jc2k> i'll briefly explain my usecase... 16:21 < Jc2k> i've been updating GNOME's jhbuild tool so it can use git-mirror.gnome.org instead of svn.gnome.org 16:22 < Jc2k> the current git support updates by git fetching and then rebasing on to of origin/master (or origin/branchname) 16:22 < doener> Jc2k: maybe you're looking for "git pull --rebase" then? 16:23 < doener> Jc2k: you can also set a config value for the branch, so "git pull" defaults to --rebase 16:23 < Jc2k> i dont think jhbuild should be tweaking config values lightly 16:24 < doener> well, if it rebases, it will likely break up any merge commits anyway 16:24 < doener> (any local-only ones, created by git pull without rebase) 16:24 < Jc2k> if git pull --rebase is equivalent to git fetch && git rebase against-branch-we-are-tacking then i'll switch to that, and send them a patch to support normal git pull as well 16:25 < doener> Jc2k: that's what --rebase does. Instead of "git fetch <remote> <refspec> && git merge FETCH_HEAD" it does "git fetch <remote> <refspec> && git rebase --onto FETCH_HEAD <old_tracking_branch_state>" (simplified) I'll put together a patch to replace git fetch / git checkout / git rebase with git pull --rebase and to allow user to not rebase as well.
Yes, I think "pull --rebase" it's what we want in the end. As a user I am not fond of it, because I prefer to check first what a "fetch" will result in remotes (how much change, where, conflict if remote did a rebase...) But for jhbuild, I think it's exactly what we are doing. Some time ago, git pull didn't had "--rebase", it is fairly recent. When I discovered it, I though about modifying jhbuild with it actually, but then, since it was so new, I decided not to. Today it should be fine, it's been about 10 month it's in git.git (0ebd5d7186237663a642397214232e5fe2fba21d, Sun Dec 2 23:00:43 2007 -0800) Do we use git svn rebase for git svn btw?
Created attachment 122654 [details] [review] Use git pull --rebase
Created attachment 122656 [details] [review] Dont checkout when updating 'jhbuild update' will force a git checkout from whatever branch is specificed in the moduleset. If user has specifically checked out a local topic branch they are working on this is probably not what they want or expect. This patch stops (most) of this. Not sure about date based checkouts.
I think the checkout change is a good one - a basic principle should be that jhbuild shouldn't should be under-aggressive rather than over-aggressive when it doen't know what is going on, and switching branches on the user probably count as over-aggressive. (It shoudn't be applied though without other changes to avoid rebasing random branches onto the source branch,) The one caveat is that if the branch is switched in the jhbuild configuration, then you don't want to keep on building the old branch. Two possible fixes for that: A) We could check out a local branch named jhbuild that is defined to always track the jhbuild-configured source branch. (So, it would track origin/master, origin/gtk-2-14, but it would be called jhbuild.) Might confuse people reading external git documentation. B) If we are on a branch that isn't what we expect, stop and ask the user 'what now?' See below. I generally like B) better. So, on to pull --rebase. To me, there are three basic situations: - The user is on the branch that jhbuild checked out. git pull --rebase and the current fetch/rebase pair work exactly the same. - The user is on a local branch that they've created (maybe for some feature work.) 'git pull --rebase' will stop and spew a huge message at the user starting with "You asked me to pull without telling me which branch you want to merge with." The user might want to: [1] leave the branch untouched, switch to master, and update that assuming that there are no local changes [2] rebase the branch against origin/master [3] ignore changes in origin/master and continue [4] get a shell and do something else I think the best thing to do is simply offer those options. I don't see any way to read the user's mind - The user is on a branch that track's something other than the jhbuild source branch. 'git pull --rebase' will rebase against that branch. There's some chance that is right - that the user really wanted to substitute some foreign version of the module or different version and override the moduleset, but more likely, they are there because the moduleset changed, or because they had a different branch checked out for some temporary work. Again, stopping the user and asking whether they want to: [1] switch to master, and update that [2] ignore changes and continue [3] get a shell and do something else Seems like the best choice.
So the plan would be to replace git fetch/git stash by git pull --rebase, and checking the current branch beforehand. I tried to translate this in "code" and git commands below, comments are appreciated, especially as I rewrote this comment too many times already, and may have forgotten things along... if branch specified in moduleset: jhbuild_branch = 'jhbuild-' + branch from moduleset else: jhbuild_branch = 'master' current_branch = $(git branch) if current_branch == jhbuild_branch: git pull --rebase return if current_branch == 'master' or current_branch.startswith('jhbuild-'): # just a change in the moduleset, user didn't play with branches git checkout --track -b jhbuild-$FOO origin/$FOO (or git checkout jhbuild-$FOO if the branch already exists) git pull --rebase return # user is on a branch unknown to jhbuild currently_tracked_branch = $(git ...) # XXX if currently_tracked_branch == jhbuild_branch: # XXX: why would it ask the user, wouldn't git pull --rebase work fine? git pull --rebase # and if it fails, propose a shell return # user is on a branch that is not the one that jhbuild should track # ask what to do: [1] git checkout master; git pull --rebase [2] do nothing [3] start shell
I changed a lot of things wrt the git support, and it should address comments raised in this bug report; in any case if some git command fails it will always offer the possibility to start a shell to fix the situation. commit bb0119d28d8d4823a493f43f165ee2575366bf73 Author: Frederic Peters <fpeters@0d.be> Date: Fri Apr 24 16:08:46 2009 +0200 improve git support in many ways Changes to a simpler support of branches; switch from git fetch/git rebase to git pull --rebase, only stash when there is a diff, and pop afterwards, and no longer use git rev-parse to check for branch existance. (GNOME #532673, #549704, #552476 and #564672)