best way to fastforward all tracking branches after a fetch
From: Gelonida N <hidden>
Date: 2016-06-15 22:52:36
Hi, What is the best way to fastforward all fastforwardable tracking branches after a git fetch?
24 messages, 9 authors, 2016-06-15 · open the first message on its own page
From: Gelonida N <hidden>
Date: 2016-06-15 22:52:36
Hi, What is the best way to fastforward all fastforwardable tracking branches after a git fetch?
From: Sitaram Chamarty <hidden>
Date: 2016-06-15 22:52:36
On Sat, Dec 10, 2011 at 01:26:32PM +0100, Gelonida N wrote:
Hi, What is the best way to fastforward all fastforwardable tracking branches after a git fetch?
I dont think there is a single command to do it for *all*
branches, but for any particular branch, this should work:
git merge --ff-only @{u}
So what you want would boil down to this script (untested):
#!/bin/bash
git status --porcelain -uno | grep . && {echo dirty tree, exiting...; exit 1; }
for b in `git for-each-ref '--format=%(refname:short)' refs/heads`
do
git checkout $b
git merge --ff-only @{u}
done
From: Gelonida N <hidden>
Date: 2016-06-15 22:52:36
On 12/11/2011 03:22 AM, Sitaram Chamarty wrote:
On Sat, Dec 10, 2011 at 01:26:32PM +0100, Gelonida N wrote:quoted
Hi, What is the best way to fastforward all fastforwardable tracking branches after a git fetch?I dont think there is a single command to do it for *all* branches, but for any particular branch, this should work:
A tiny script is fine. I didn't really expect the magic command. Currently I'm using one script per repository, which hard coded the branches, that I want to fast-forward (checking them out and doing a git-pull)
git merge --ff-only @{u}Thanks, '--ff=only @{u}' is already the first improvement for my script.
So what you want would boil down to this script (untested):
#!/bin/bash
git status --porcelain -uno | grep . && {echo dirty tree, exiting...; exit 1; }
for b in `git for-each-ref '--format=%(refname:short)' refs/heads`
do
git checkout $b
git merge --ff-only @{u}
doneIs there no way to distinguish tracking branches from other branches? without checking them out? In order to save time I'd like to avoid checking out local branches. Ideally I would even like to avoid checking out branches, which don't need to be forwarded. I also had to remember on which branch I was in order to avoid, that I am at a random branch after running the script. I could imagine something like my snippet below , though I guess, there's something more elegant. git stash mybranch=`git branch | sed -n 's/\* *//p'` # do_script . . . git checkout $mybranch git stash apply
From: Martin Langhoff <hidden>
Date: 2016-06-15 22:52:36
On Sat, Dec 10, 2011 at 7:26 AM, Gelonida N [off-list ref] wrote:
What is the best way to fastforward all fastforwardable tracking branches after a git fetch?
It'd be a great addition to git fetch ;-) m -- martin.langhoff@gmail.com martin@laptop.org -- Software Architect - OLPC - ask interesting questions - don't get distracted with shiny stuff - working code first - http://wiki.laptop.org/go/User:Martinlanghoff
From: Jakub Narebski <hidden>
Date: 2016-06-15 22:52:36
Don't remove people from Cc, please. Gelonida N [off-list ref] writes:
On 12/11/2011 03:22 AM, Sitaram Chamarty wrote:quoted
On Sat, Dec 10, 2011 at 01:26:32PM +0100, Gelonida N wrote:
quoted
So what you want would boil down to this script (untested): #!/bin/bash git status --porcelain -uno | grep . && {echo dirty tree, exiting...; exit 1; } for b in `git for-each-ref '--format=%(refname:short)' refs/heads` do git checkout $b git merge --ff-only @{u} doneIs there no way to distinguish tracking branches from other branches? without checking them out? In order to save time I'd like to avoid checking out local branches.
You can use 'upstream' field name in git-for-each-ref invocation, for example git for-each-ref '--format=%(refname:short) %(upstream:short)' refs/heads | grep -e ' [^ ]' | sed -e 's/ .*$// This could probably be done using only sed -- grep is not necessary.
Ideally I would even like to avoid checking out branches, which don't need to be forwarded.
You can use git-update-ref plumbing, but you would have to do the check if it does fast-forward yourself, and provide reflog message yourself too. Something like git for-each-ref '--format=%(refname) %(upstream)' | while read refname upstream do # there is upstream test -n "$upstream" || break # and if fast-forwards test $(git merge-base $refname $upstream) = $(git rev-parse $refname) || break git update-ref -m "$message" $refname $upstream done
I also had to remember on which branch I was in order to avoid, that I am at a random branch after running the script. I could imagine something like my snippet below , though I guess, there's something more elegant. git stash mybranch=`git branch | sed -n 's/\* *//p'` # do_script . . . git checkout $mybranch git stash apply
Don't use git-branch in scripting. See __git_ps1 function in contrib/completion/git-completion.bash how it can be done: b="$(git symbolic-ref HEAD 2>/dev/null)" || b="$(git rev-parse --verify HEAD)" Nb. the second part is here only if there is possibility that you are on detached HEAD (unnamed branch). HTH (hope that helps) -- Jakub Narębski
From: Sitaram Chamarty <hidden>
Date: 2016-06-15 22:52:36
2011/12/11 Jakub Narebski [off-list ref]:
Don't remove people from Cc, please. Gelonida N [off-list ref] writes:quoted
On 12/11/2011 03:22 AM, Sitaram Chamarty wrote:quoted
On Sat, Dec 10, 2011 at 01:26:32PM +0100, Gelonida N wrote:quoted
quoted
So what you want would boil down to this script (untested): #!/bin/bash git status --porcelain -uno | grep . && {echo dirty tree, exiting...; exit 1; } for b in `git for-each-ref '--format=%(refname:short)' refs/heads` do git checkout $b git merge --ff-only @{u} doneIs there no way to distinguish tracking branches from other branches? without checking them out? In order to save time I'd like to avoid checking out local branches.You can use 'upstream' field name in git-for-each-ref invocation, for example git for-each-ref '--format=%(refname:short) %(upstream:short)' refs/heads | grep -e ' [^ ]' | sed -e 's/ .*$// This could probably be done using only sed -- grep is not necessary.quoted
Ideally I would even like to avoid checking out branches, which don't need to be forwarded.You can use git-update-ref plumbing, but you would have to do the check if it does fast-forward yourself, and provide reflog message yourself too.
if it's not the currently checked-out branch, 'git branch -f foo origin/foo' seems to work fine. However, it only updates the branch reflog, not the HEAD reflog also, naturally. FWIW...
Something like git for-each-ref '--format=%(refname) %(upstream)' | while read refname upstream do # there is upstream test -n "$upstream" || break # and if fast-forwards test $(git merge-base $refname $upstream) = $(git rev-parse $refname) || break git update-ref -m "$message" $refname $upstream donequoted
I also had to remember on which branch I was in order to avoid, that I am at a random branch after running the script. I could imagine something like my snippet below , though I guess, there's something more elegant. git stash mybranch=`git branch | sed -n 's/\* *//p'` # do_script . . . git checkout $mybranch git stash applyDon't use git-branch in scripting. See __git_ps1 function in contrib/completion/git-completion.bash how it can be done: b="$(git symbolic-ref HEAD 2>/dev/null)" || b="$(git rev-parse --verify HEAD)" Nb. the second part is here only if there is possibility that you are on detached HEAD (unnamed branch). HTH (hope that helps) -- Jakub Narębski
-- Sitaram
From: Gelonida N <hidden>
Date: 2016-06-15 22:52:36
On 12/11/2011 07:22 PM, Jakub Narebski wrote:
Don't remove people from Cc, please.
OK,
Gelonida N [off-list ref] writes:quoted
On 12/11/2011 03:22 AM, Sitaram Chamarty wrote:
quoted
In order to save time I'd like to avoid checking out local branches.You can use 'upstream' field name in git-for-each-ref invocation, for example git for-each-ref '--format=%(refname:short) %(upstream:short)' refs/heads | grep -e ' [^ ]' | sed -e 's/ .*$//
Thanks
This could probably be done using only sed -- grep is not necessary.
I think the equivalent would be: sed '/ [^ ]/ s/ .*$//'
quoted
Ideally I would even like to avoid checking out branches, which don't need to be forwarded.You can use git-update-ref plumbing, but you would have to do the check if it does fast-forward yourself, and provide reflog message yourself too.
True this would probably be fastest. Will read the docs a little to understand exactly what you're doing. I'm not that much used to all the commands used in the script.
Something like git for-each-ref '--format=%(refname) %(upstream)' | while read refname upstream do # there is upstream test -n "$upstream" || break # and if fast-forwards test $(git merge-base $refname $upstream) = $(git rev-parse $refname) || break git update-ref -m "$message" $refname $upstream donequoted
I also had to remember on which branch I was in order to avoid, that I am at a random branch after running the script.
Don't use git-branch in scripting. See __git_ps1 function in contrib/completion/git-completion.bash how it can be done: b="$(git symbolic-ref HEAD 2>/dev/null)" || b="$(git rev-parse --verify HEAD)" Nb. the second part is here only if there is possibility that you are on detached HEAD (unnamed branch). HTH (hope that helps)
It definitely helps. Thanks a lot. It's always good to see how one can do better after some attempts o some self made clumsy scripts not suing all the features of git.
From: Stefan Haller <hidden>
Date: 2016-06-15 22:52:36
Gelonida N [off-list ref] wrote:
What is the best way to fastforward all fastforwardable tracking branches after a git fetch?
Here's a script that does this. It isn't very well tested, I hope I
didn't miss any edge cases. Use at your own risk.
(It doesn't fastforward the branch you're on, on the assumtion that if
you said git fetch instead of git pull, you probably had a reason.)
========= 8< =========
#!/bin/sh
currentbranch="`git symbolic-ref HEAD 2>/dev/null`"
git for-each-ref --shell --format='ref=%(refname);upstream=%(upstream)' \
refs/heads | \
while read entry
do
eval "$entry"
# skip the current branch
test "$ref" = "$currentbranch" && continue
# skip branches that have no upstream
test -z "$upstream" && continue
# skip if upstream doesn't have any new commits
if [ -z "`git rev-list "$ref..$upstream"`" ]; then
echo "${ref#refs/heads/} is up to date"
continue
fi
# error if there are local commits
if [ -n "`git rev-list "$upstream..$ref"`" ]; then
echo "${ref#refs/heads/} has local commits; can't fast-forward"
continue
fi
echo "${ref#refs/heads/} -> ${upstream#refs/remotes/}"
git update-ref -m ff-all-branches "$ref" "$upstream"
done
========= >8 =========
--
Stefan Haller
Berlin, Germany
http://www.haller-berlin.de/
From: Gelonida N <hidden>
Date: 2016-06-15 22:52:36
On 12/11/2011 09:14 PM, Stefan Haller wrote:
Gelonida N [off-list ref] wrote:quoted
What is the best way to fastforward all fastforwardable tracking branches after a git fetch?Here's a script that does this. It isn't very well tested, I hope I didn't miss any edge cases. Use at your own risk. (It doesn't fastforward the branch you're on, on the assumtion that if you said git fetch instead of git pull, you probably had a reason.)
Agreed. it might be reasonable to ignore the current branch if it wasn't pulled. Thanks a lot for the script. I will play with it.
From: Martin Langhoff <hidden>
Date: 2016-06-15 22:52:36
On Sun, Dec 11, 2011 at 3:27 PM, Gelonida N [off-list ref] wrote:
Agreed. it might be reasonable to ignore the current branch if it wasn't pulled.
Actually, what this means is that this should be an enhancement to git
pull ("git pull --all") because pull means fetch + merge.
cheers,
m
--
martin.langhoff@gmail.com
martin@laptop.org -- Software Architect - OLPC
- ask interesting questions
- don't get distracted with shiny stuff - working code first
- http://wiki.laptop.org/go/User:Martinlanghoff
From: Hallvard B Furuseth <hidden>
Date: 2016-06-15 22:52:36
Stefan Haller writes:
Gelonida N [off-list ref] wrote:quoted
What is the best way to fastforward all fastforwardable tracking branches after a git fetch?Here's a script that does this. It isn't very well tested, I hope I didn't miss any edge cases. Use at your own risk.
Local branches can track each other. So the script needs to toposort the branches, or to loop until either nothing was done or an error happened. (The latter to prevent an eternal loop on error.) I've wished for a more limited 'git ff' command than this: - git update-ref --ff-only, and branch/fetch options based on this. - Fast-forward only the branches tracking one particular remote/branch, and maybe branches tracking the fast-forwarded branches. - Fast-forward to another remote or branch than the tracked one. I have a few aliases for it, but never thought much of a good common design. -- Hallvard
From: Stefan Haller <hidden>
Date: 2016-06-15 22:52:36
Hallvard B Furuseth [off-list ref] wrote:
Stefan Haller writes:quoted
Gelonida N [off-list ref] wrote:quoted
What is the best way to fastforward all fastforwardable tracking branches after a git fetch?Here's a script that does this. It isn't very well tested, I hope I didn't miss any edge cases. Use at your own risk.Local branches can track each other. So the script needs to toposort the branches, or to loop until either nothing was done or an error happened. (The latter to prevent an eternal loop on error.)
Is this just theoretical, or are there real use cases for this? What would be a workflow with such a local tracking branch? For me personally, the script is good enough, because I only ever have branches that track an 'origin' branch with the same name. -- Stefan Haller Berlin, Germany http://www.haller-berlin.de/
From: Jeff King <hidden>
Date: 2016-06-15 22:52:37
On Mon, Dec 12, 2011 at 08:33:15AM +0100, Stefan Haller wrote:
quoted
Local branches can track each other. So the script needs to toposort the branches, or to loop until either nothing was done or an error happened. (The latter to prevent an eternal loop on error.)Is this just theoretical, or are there real use cases for this? What would be a workflow with such a local tracking branch?
I use this all the time.
In git.git, we use a topic branch workflow (i.e., every feature gets its
own topic branch, and topics graduate independently to master as they
are deemed stable). And we use a patch-submission workflow, which means
it's OK for me to rebase my topics locally, because the end-product is a
series of patches sent to the list.
Typically I branch off of "origin/master", so the topic is independent
of anything else. For example, the "jk/credentials" branch in my git
repo is branched from "origin/master" (Junio's master). But sometimes
there is a topic that depends on another topic, but should not be part
of the same series (because the the first topic can graduate to master,
but the second one may still need more time for discussion and cooking).
In that case, I'll set the upstream to the other local topic branch. An
example of this is the "jk/prompt" series, which depends on
"jk/credentials" for infrastructure, but is really a separate issue.
Having the upstream set is convenient, because I can get _just_ the
commits in jk/prompt with "git log @{u}..". Or I can rebase _just_ the
commits in that topic with "git rebase -i". If my upstream were set to
origin, I would accidentally also rebase all of the commits pulled in
from jk/credentials, too.
While my topics are still in development (i.e., before they have even
hit "next"), I tend to rebase them aggressively (so that I keep them up
to date with git development), using a script that is something like[1]:
for i in `topics`; do
git rebase $i@{u} $i
done
And I do topo-sort my topics for exactly the reason mentioned.
-Peff
[1] https://github.com/peff/git/blob/meta/rebase
From: Junio C Hamano <hidden>
Date: 2016-06-15 22:52:37
Gelonida N [off-list ref] writes:
What is the best way to fastforward all fastforwardable tracking branches after a git fetch?
This lacks context and invites too many tangents, so I'll only touch a few
of them.
First of all, why do you want to do this?
You have many local branches that are forked from remote tracking branches
and can be fast-forwarded to their counterparts, iow, these local branches
are often behind their upstream and you do not have your own development
in this repository. Because you can by definition have only one branch
checked out in your working tree, after a fetch from your origin, they
will further fall behind their counterparts.
Coming from that background, I can see you may want these branches that
are not checked out fast-forwarded to their remote counterparts to keep
them stay current, but I first question that background. Why have these
local branches to begin with, if they always are supposed to match their
remote counterpart?
One possible reason (this is one tangent) is that you want to build and
install tips of many branches fetched from the upstream without doing any
local development in this repository (the "upstream" could be your primary
repository and the changes fed to this repository may be your own
development, so this is different from saying that you as a person is only
following other people's work. It is just that nothing is done to the
history in THIS repository). It could be solved by directly checking out
the remote tracking branches into detached head state, e.g.
$ for branch in maint master next
do
git checkout origin/$branch &&
make prefix=$HOME/git-$branch all test install || break
done
and the reason why you want local branches instead may be because your
build infrastructure (i.e. instead of "make" you have a custom script,
just like I use 'Make' script in my 'todo' branch) the does customization
depending on the name of the current branch, and might be more cumbersome
to get the same information for a detached head state (i.e. "the tip of
which remote tracking branch is the current commit?") than asking "git
symbolic-ref" the name of the current branch. But then it is easy to find
out which remote branch was checked out from the reflog for the HEAD (and
it is easier for your script that builds the origin/$branch to use that
information internally when the script calls your 'Make' equivalent). In
any case, it is largely your build customization's problem if this is the
case.
Another tangent. Perhaps the reason why you want these local branches but
they can often be fast-forwarded is because your workflow looks like this:
(1) you fork a topic from origin/master;
(2) you develop a bit;
(3) you push the topic back to origin/master;
(4) time passes, others push to origin/master, while you work on other
branches of yours;
(5) from time to time, you fetch from origin;
(6) you decide to continue working on the topic, so you check it out,
and before continuing, you wish it is already up-to-date.
But then after fast-forwarding the topic in (6), your topic's history
contains commits other than those you made to work toward the goal of your
topic, namely, other commits made by others during (4) for random purposes
that do not have anything to do with achieving the goal of the topic of
yours. Your branch is no longer about what you wanted to accomplish on
your topic. This invites two tangents.
One is a question. If you knew that the topic is not cooked fully and
needs further work after step (6), why did you push it back to the
origin/master in the first place at step (3), contaminating the history
everybody else bases their further work on with the contents of your
"half-done" topic?
Another tangent. Perhaps the fork is not made from origin/master but you
are collaboratively working on the same topic with others, and you handed
off the work up to what you have done at step (3), and others continued to
further the goal of the shared topic during (4). If that is the case,
wouldn't it make more sense to delete the topic after you push it back,
and forking at the point when you actually decide to get back into action?
Yet another. Even if you keep the (stale) topic branch that you already
have pushed out to the remote, because you can work on one topic at a time
in a single working tree anyway, perhaps it makes more sense to delay this
fast-forwarding until you actually check out the topic branch? After all,
your wishing to fast-forward "all branches" imply you have many of them,
and it wouldn't be far-fetched for me to imagine that you will check one
of them out a lot less often than you run "git fetch".
In other words, wouldn't a post-checkout hook be a better place to do
this kind of thing, perhaps like this (completely untested)?
#!/bin/sh
old=$1 new=$2 kind=$3
# did we checkout a branch?
test "$kind" = 1 || exit 0
# what did we check out?
branch=$(git symbolic-ref HEAD 2>/dev/null) || exit 0
# does it track anything? otherwise nothing needs to be done
upstream=$(git for-each-ref --format='%(upstream)' "$branch")
test -z "$upstream" || exit 0
# are we up-to-date? if so no need to do anything
test 0 = $(git rev-list "..$upstream" | wc -l) && exit 0
# do we have something we made? if so no point trying to fast-forward
test 0 = $(git rev-list "$upstream.." | wc -l) || exit 0
# attempt a fast-forward merge with it
git merge --ff-only @{upstream}
That is, of course, assuming that it makes sense to keep these local
branches in the first place.
From: Junio C Hamano <hidden>
Date: 2016-06-15 22:52:37
Hallvard B Furuseth [off-list ref] writes:
Local branches can track each other. So the script needs to toposort the branches, or to loop until either nothing was done or an error happened. (The latter to prevent an eternal loop on error.)
If you have branches A that forked from B that in turn forked from C, and if after updating C you want to and can successfully update both B and A by fast-forwarding, that would only mean that neither A nor B had their own change since they were forked from their upstream, regardless of local or remote. What use do these empty branches have in the first place?
From: Stefan Haller <hidden>
Date: 2016-06-15 22:52:37
Jeff King [off-list ref] wrote:
On Mon, Dec 12, 2011 at 08:33:15AM +0100, Stefan Haller wrote:quoted
quoted
Local branches can track each other. So the script needs to toposort the branches, or to loop until either nothing was done or an error happened. (The latter to prevent an eternal loop on error.)Is this just theoretical, or are there real use cases for this? What would be a workflow with such a local tracking branch?I use this all the time. In git.git, we use a topic branch workflow (i.e., every feature gets its own topic branch, and topics graduate independently to master as they are deemed stable). And we use a patch-submission workflow, which means it's OK for me to rebase my topics locally, because the end-product is a series of patches sent to the list. Typically I branch off of "origin/master", so the topic is independent of anything else. For example, the "jk/credentials" branch in my git repo is branched from "origin/master" (Junio's master). But sometimes there is a topic that depends on another topic, but should not be part of the same series (because the the first topic can graduate to master, but the second one may still need more time for discussion and cooking). In that case, I'll set the upstream to the other local topic branch. An example of this is the "jk/prompt" series, which depends on "jk/credentials" for infrastructure, but is really a separate issue. Having the upstream set is convenient, because I can get _just_ the commits in jk/prompt with "git log @{u}..". Or I can rebase _just_ the commits in that topic with "git rebase -i". If my upstream were set to origin, I would accidentally also rebase all of the commits pulled in from jk/credentials, too.
I see, thanks. For my script, I'm wondering then if the most sensible thing to do is to just skip any branch whose upstream doesn't start with refs/remotes/. For a future "git pull --all" feature, it would probably only work on those branches whose upstream is on the remote being pulled from, anyway. -- Stefan Haller Berlin, Germany http://www.haller-berlin.de/
From: Gelonida N <hidden>
Date: 2016-06-15 22:52:37
Thanks for this rather long answer, On 12/12/2011 09:09 AM, Junio C Hamano wrote:
Gelonida N [off-list ref] writes:quoted
What is the best way to fastforward all fastforwardable tracking branches after a git fetch?This lacks context and invites too many tangents, so I'll only touch a few of them. First of all, why do you want to do this?
To explain the scenario: - small project - every person works on master and multiple topic branches and might alternate rather often - sometimes several persons work on the same topic branch but most of the time not in parallel. - one person is working from several machines (starting work on one and continuing on another) - additionally we do many pushed in order to be sure, that our data is backed up in case of disk failures. - sometimes I just want to 'build' from a branch, that I am not working on. but there I create mostly not even a tracking branch before changing a machine I want to be sure to have pushed everything. I wanted to get rid of the warning, that some branches cannot be pushed, because they aren't fastforwarded when checking out a branch I want to avoid, that I have to pull manually.
In other words, wouldn't a post-checkout hook be a better place to do
this kind of thing, perhaps like this (completely untested)?
#!/bin/sh
old=$1 new=$2 kind=$3
# did we checkout a branch?
test "$kind" = 1 || exit 0
# what did we check out?
branch=$(git symbolic-ref HEAD 2>/dev/null) || exit 0
# does it track anything? otherwise nothing needs to be done
upstream=$(git for-each-ref --format='%(upstream)' "$branch")
test -z "$upstream" || exit 0
# are we up-to-date? if so no need to do anything
test 0 = $(git rev-list "..$upstream" | wc -l) && exit 0
# do we have something we made? if so no point trying to fast-forward
test 0 = $(git rev-list "$upstream.." | wc -l) || exit 0
# attempt a fast-forward merge with it
git merge --ff-only @{upstream}This is a solution, I wouldn't get rid of the warnings though when running git push.
From: Gelonida N <hidden>
Date: 2016-06-15 22:52:37
I forgot one other use case: - wanting to pull from tracking branches without fastforwarding is not such a smart idea. of course I can do git merge from remotes/origin/branch but this is more to type and would vary depending on whether 'd like to pull from an unpushed tracking branch or from a freshly fetched tracking branch. On 12/12/2011 11:13 AM, Gelonida N wrote:
Thanks for this rather long answer, On 12/12/2011 09:09 AM, Junio C Hamano wrote:quoted
Gelonida N [off-list ref] writes:quoted
What is the best way to fastforward all fastforwardable tracking branches after a git fetch?This lacks context and invites too many tangents, so I'll only touch a few of them. First of all, why do you want to do this?To explain the scenario: - small project - every person works on master and multiple topic branches and might alternate rather often - sometimes several persons work on the same topic branch but most of the time not in parallel. - one person is working from several machines (starting work on one and continuing on another) - additionally we do many pushed in order to be sure, that our data is backed up in case of disk failures. - sometimes I just want to 'build' from a branch, that I am not working on. but there I create mostly not even a tracking branch before changing a machine I want to be sure to have pushed everything. I wanted to get rid of the warning, that some branches cannot be pushed, because they aren't fastforwarded when checking out a branch I want to avoid, that I have to pull manually.quoted
In other words, wouldn't a post-checkout hook be a better place to do this kind of thing, perhaps like this (completely untested)? #!/bin/sh old=$1 new=$2 kind=$3 # did we checkout a branch? test "$kind" = 1 || exit 0 # what did we check out? branch=$(git symbolic-ref HEAD 2>/dev/null) || exit 0 # does it track anything? otherwise nothing needs to be done upstream=$(git for-each-ref --format='%(upstream)' "$branch") test -z "$upstream" || exit 0 # are we up-to-date? if so no need to do anything test 0 = $(git rev-list "..$upstream" | wc -l) && exit 0 # do we have something we made? if so no point trying to fast-forward test 0 = $(git rev-list "$upstream.." | wc -l) || exit 0 # attempt a fast-forward merge with it git merge --ff-only @{upstream}This is a solution, I wouldn't get rid of the warnings though when running git push.
From: Hallvard Breien Furuseth <hidden>
Date: 2016-06-15 22:52:37
Stefan Haller writes:
Hallvard B Furuseth [off-list ref] wrote:quoted
Local branches can track each other. So the script needs to toposort the branches, or to loop until either nothing was done or an error happened. (The latter to prevent an eternal loop on error.)Is this just theoretical, or are there real use cases for this? What would be a workflow with such a local tracking branch?
Personally I don't care much, I just noted that the script did not match the question in the subject line. -- Hallvard
From: Sitaram Chamarty <hidden>
Date: 2016-06-15 22:52:39
On Sat, Dec 10, 2011 at 01:26:32PM +0100, Gelonida N wrote:
Hi, What is the best way to fastforward all fastforwardable tracking branches after a git fetch?
I know this is a somewhat closed topic, but I took some time to
clean up a program I have been using for a while, including some
changes based upon ideas elsewhere in this thread. The program
"git-branch-check" is attached, and requires perl > 5.10.0.
Note that this does a lot more than just fast-forward all
branches, although it can do that as well.
I alias it (in ~/.gitconfig) to 'bc', so I just run "git bc".
Running with "-h" shows usage:
Usage: /home/sitaram/bin/git-branch-check [options] [branches]
Check or fast forward branches. Default: act upon all local branches if no
arguments supplied, or just the current branch if '-c' is passed.
-c act upon current branch only
-ff don't just check, try to fast forward also
-md max diff (default 100; see below for details)
-h help
'max diff':
hide output for two branches different by more than so many commits
My usual usage is just "git bc -c", which may give me:
1 pu...origin/pu
1 pu...github/pu
13 pu...master
5 pu...q
7 pu...vrs
This quickly tells me my 'pu' is one ahead of both my own
gitolite server as well as github's copy, and that it is 13
commits ahead of master. The (unreleased and frequently
rebased) feature branches 'q' and 'vrs' are ahead of pu, which
means a rebase is not pending. Without the "-c" I may see the
status of master versus its own upstream and other remotes,
etc., also.
The purpose of the max diff limit (default 100) is to hide, for
example, the pair 'master' and 'man' from the git.git repo.
Otherwise you'd see something like:
27249 973 master...man
which is pretty meaningless. The sum of those two numbers
should be less than the max.
"git bc -ff" will attempt to fast forward all selected branches
that are ancestors of their respective upstreams. The current
branch will not be ff-ed if the tree is dirty, since you can't
do this by 'git branch -f'; it has to be an actual merge
command.
The output is not (currently) pipable to other programs because
I use colors (obtained from 'git config --get-color') and
currently it is not conditional on STDOUT being a tty.
From: Sitaram Chamarty <hidden>
Date: 2016-06-15 22:52:39
oops; forgot the program... On Sat, Dec 17, 2011 at 03:40:09PM +0530, Sitaram Chamarty wrote:
On Sat, Dec 10, 2011 at 01:26:32PM +0100, Gelonida N wrote:quoted
Hi, What is the best way to fastforward all fastforwardable tracking branches after a git fetch?I know this is a somewhat closed topic, but I took some time to clean up a program I have been using for a while, including some changes based upon ideas elsewhere in this thread. The program "git-branch-check" is attached, and requires perl > 5.10.0. Note that this does a lot more than just fast-forward all branches, although it can do that as well. I alias it (in ~/.gitconfig) to 'bc', so I just run "git bc". Running with "-h" shows usage: Usage: /home/sitaram/bin/git-branch-check [options] [branches] Check or fast forward branches. Default: act upon all local branches if no arguments supplied, or just the current branch if '-c' is passed. -c act upon current branch only -ff don't just check, try to fast forward also -md max diff (default 100; see below for details) -h help 'max diff': hide output for two branches different by more than so many commits My usual usage is just "git bc -c", which may give me: 1 pu...origin/pu 1 pu...github/pu 13 pu...master 5 pu...q 7 pu...vrs This quickly tells me my 'pu' is one ahead of both my own gitolite server as well as github's copy, and that it is 13 commits ahead of master. The (unreleased and frequently rebased) feature branches 'q' and 'vrs' are ahead of pu, which means a rebase is not pending. Without the "-c" I may see the status of master versus its own upstream and other remotes, etc., also. The purpose of the max diff limit (default 100) is to hide, for example, the pair 'master' and 'man' from the git.git repo. Otherwise you'd see something like: 27249 973 master...man which is pretty meaningless. The sum of those two numbers should be less than the max. "git bc -ff" will attempt to fast forward all selected branches that are ancestors of their respective upstreams. The current branch will not be ff-ed if the tree is dirty, since you can't do this by 'git branch -f'; it has to be an actual merge command. The output is not (currently) pipable to other programs because I use colors (obtained from 'git config --get-color') and currently it is not conditional on STDOUT being a tty.
From: Nazri Ramliy <hidden>
Date: 2016-06-15 22:52:40
On Sat, Dec 17, 2011 at 6:11 PM, Sitaram Chamarty [off-list ref] wrote:
oops; forgot the program...
This is nice! Stick it on github, or somewhere, please, so that I can always get the latest and greatest? Thanks. nazri
From: Sitaram Chamarty <hidden>
Date: 2016-06-15 22:52:49
On Sat, Dec 17, 2011 at 3:40 PM, Sitaram Chamarty [off-list ref] wrote:
On Sat, Dec 10, 2011 at 01:26:32PM +0100, Gelonida N wrote:quoted
Hi, What is the best way to fastforward all fastforwardable tracking branches after a git fetch?I know this is a somewhat closed topic, but I took some time to clean up a program I have been using for a while, including some
A month later and I find I have modified this program
From: Sitaram Chamarty <hidden>
Date: 2016-06-15 22:52:49
(sorry about that previous email; hit send in error. Here's the complete one) On Mon, Dec 19, 2011 at 12:01 PM, Nazri Ramliy [off-list ref] wrote:
On Sat, Dec 17, 2011 at 6:11 PM, Sitaram Chamarty [off-list ref] wrote:quoted
oops; forgot the program...This is nice! Stick it on github, or somewhere, please, so that I can always get the latest and greatest? Thanks. nazri
ok; it's on github: http://github.com/sitaramc/git-tools (they're all standalone tools; you don't have to use the others) The output is now colorised, and it will now also tell you, for each remote you have, what branches you are hiding from them and what they have which you have not started tracking locally. a "screenshot" is at http://sitaramc.github.com/git-tools/index.html#index_git_branch_check_ I notice I'm using it more and more, often even as a replacement for 'git status'... at least for repos where I'm juggling multiple remotes.