Re: [PATCH] Added guilt.reusebranch configuration option.

5 messages, 3 authors, 2016-06-15 · open the first message on its own page

Re: [PATCH] Added guilt.reusebranch configuration option.

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:57:24

Theodore Ts'o [off-list ref] writes:
On Wed, May 22, 2013 at 10:58:49AM -0700, Junio C Hamano wrote:
quoted
Theodore Ts'o [off-list ref] writes:
quoted
I was actually thinking that it might be interesting to have a
branch.<branch>.rewindable, which would change the guilt defaults, and
could also key changes in key git behavior which makes it less likely
that a user shoots him or herself in the foot --- i.e., give warnings
if he or she has modified the branch in such a way that
remotes.origin.<branch> is no longer contained within the branch head.
At least "rebase" can pay attention to it and might make the world a
better place.
Yeah, rebase was the primary command I was thinking about.  The other
one would be "git commit --amend" after the branch had been pushed
out.
It may or may not matter for the kernel folks, but let me pick your
brain while we are on this subject.

The "upstream" (your remotes.origin.<branch>) is that on top of
which you build your work.  You clone from there to bootstrap
yourself, you add your work (which may include integrating the work
of your contributors, if you are a mid-tier maintainer/integrator
aka a lieutenant) on top of it, and arrange the result to reach the
"upstream" in some way.

For the simplest (and still widely used) workflow that employs a
central shared repository, the way to make the result to reach the
"upstream" is by directly pushing into it yourself.  In that sense,
the word "upstream" and the traditional behaviour of "git push" that
pushes back to the 'origin' (or branch.<branch>.remote) to update
your "upstream" (or branch.<branch>.merge at 'origin') both make
perfect sense.

Also, if you are rebasing, @{u} refers to that place you integrate
with, i.e. your "upstream", in the central shared repository
workflow.

But in a triangular workflow, the way to make the result reach the
"upstream" is *not* by pushing there yourself.  For developers at
the leaf level, it is to push to their own repository (often on
GitHub), which is different from where they (initially) clone from
in order to bootstrap themselves, and (subsequently) pull from in
order to keep them up-to-date.  And then they request the published
work to be pulled by the "upstream".

Even in a triangular workflow, @{u} should still refer to the place
you integrate with, i.e. your "upstream", not to the place you push
to publish the result of your work.

This branch.<branch>.rewindable safety however cannot be tied to
@{u}.  The bottom boundary you want to be warned when you cross is
the change you pushed out to your publishing repository, and it may
not have reached remotes.origin.<branch> yet.

We will be introducing remote.pushdefault configuration in the
upcoming 1.8.3 release, so that you can say:

	[remote "origin"]
        	url = git://g.k.o/pub/scm/linux/kernel/git/torvalds/linux.git/
		fetch = +refs/heads/*:refs/remotes/origin/*

	[remote "ext4"]
        	url = g.k.o:/pub/scm/linux/kernel/git/tytso/ext4.git/
		fetch = +refs/heads/*:refs/remotes/ext4/*

	[remote]
        	pushdefault = ext4

and hopefully it would let you do this:

	git checkout master
        ... after working on it ...
        git push

As remote.pushdefault is set to ext4, without any extra arguments,
the result will pushed to the "ext4" remote.  If you are using the
traditional push.default=matching, it may also try to push out dev,
dev-next and other branches you may have in your local repository
and at k.org; if you are using push.default=simple or other "single
branch" modes like "current", "upstream", etc, it will only push out
your current branch (i.e. "master") to "ext4" remote.

You may however be using your local "master" branch for your
development, and pushing the result out to "dev".  With only the
remote.pushdefault setting to push to ext4 (instead of origin), you
still would have to say

	git push ext4 master:dev

There is another change discussed on the list recently to also let
you configure your local "master" branch to update "dev" in your
publishing repository.  It may go like this:

	[branch "master"]
        	push = refs/heads/dev

In any case, refs/remotes/ext4/dev would be the remote tracking
branch (not refs/remotes/origin/anything) that keeps track of what
you pushed out there the last time.  And that would be what your new
safety based on "branch.master.rewindable = no" needs to check
against, not "refs/remotes/origin/master" which is your master@{u}.

Re: [PATCH] Added guilt.reusebranch configuration option.

From: Theodore Ts'o <tytso@mit.edu>
Date: 2016-06-15 22:57:24

On Wed, May 22, 2013 at 11:55:00AM -0700, Junio C Hamano wrote:
But in a triangular workflow, the way to make the result reach the
"upstream" is *not* by pushing there yourself.  For developers at
the leaf level, it is to push to their own repository (often on
GitHub), which is different from where they (initially) clone from
in order to bootstrap themselves, and (subsequently) pull from in
order to keep them up-to-date.  And then they request the published
work to be pulled by the "upstream".
Yep, what I do personally is to call the destination of this "publish", i.e.:

[remote "publish"]
	url = ssh://gitolite@ra.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.g
	push = +master:master
	push = +origin:origin
	push = +dev:dev

So my typical work flow when I am ready to submit to Linus is:

   git tag -s ext4_for_linus
   git push publish
    <wait for this to propagate from ra.kernel.org to git.kernel.org,
     typically ~5 minutes>
   git request-pull git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4.git origin > /tmp/pull
    <use /tmp/pull as the e-mail body to send to Linus, cc'ing
     LKML and linux-ext4@vger.kernel.org>

But actually, it's much more common that I am doing a "git push
publish" so that (a) it can get picked up by the daily linux-next tree
(for integration testing even before Linus pulls it into his tree),
and (b) so other ext4 developers so they can either test or develop
against the ext4 tree in progress.

I suppose it would be convenient for "git push" to push to the
"publish" target, but I don't get confused about pushing to origin,
since semantically what I am doing is publishing the current state of
the ext4 tree so other people can see it.  So "git push publish" makes
a lot of sense to me.
Even in a triangular workflow, @{u} should still refer to the place
you integrate with, i.e. your "upstream", not to the place you push
to publish the result of your work.

This branch.<branch>.rewindable safety however cannot be tied to
@{u}.  The bottom boundary you want to be warned when you cross is
the change you pushed out to your publishing repository, and it may
not have reached remotes.origin.<branch> yet.
Indeed, and in fact for my use case what I promise people is that all
of the commits between origin..master are non-rewindable.  It's the
commits betewen master..dev which are rewindable.  So for me, I'd
still use the safety feature even for my rewindable branch, but
instead of using remotes/publish/dev the "no-rewind" point, I'd want
to use remotes/publish/master as the "no-rewind" point.

Right now I do this just by being careful, but if there was an
automatic safety mechanism, it would save me a bit of work, since
otherwise I might not catch my mistake until I do the "git push
publish", at which point I curse and then start consulting the reflog
to back the state of my tree out, and then reapplying the work I had
to the right tree.
We will be introducing remote.pushdefault configuration in the
upcoming 1.8.3 release, so that you can say.....

and hopefully it would let you do this:

	git checkout master
        ... after working on it ...
        git push
Yes, that would be convenient.  BTW, one of the other things which I
do for e2fsprogs is that I use multiple publishing points, which is
mostly for historical reasons --- it used to be that repo.or.cz wasn't
all that reliable, and the 10-15 minute replication time from
ra.kernel.org to git.kernel.org got really old.

So what I do is something like this:

git push publish ; git push repo ; git push code

where....

[remote "publish"]
	url = ssh://gitolite@ra.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
	fetch = +refs/heads/*:refs/heads/*
	push = next
	push = master
	push = maint
	push = debian
	push = +pu

[remote "code"]
	url = https://code.google.com/p/e2fsprogs/
	fetch = +refs/heads/*:refs/heads/*
	push = next
	push = master
	push = maint
	push = debian
	push = +pu

[remote "repo"]
	url = ssh://repo.or.cz/srv/git/e2fsprogs.git
	push = next
	push = master
	push = maint
	push = debian
	push = +pu

I don't know if this is something you'd want git to encourage, or
support explicitly, but I thought I'd mention it.

						- Ted

Re: [PATCH] Added guilt.reusebranch configuration option.

From: Ramkumar Ramachandra <hidden>
Date: 2016-06-15 22:57:25

Theodore Ts'o wrote:
Right now I do this just by being careful, but if there was an
automatic safety mechanism, it would save me a bit of work, since
otherwise I might not catch my mistake until I do the "git push
publish", at which point I curse and then start consulting the reflog
to back the state of my tree out, and then reapplying the work I had
to the right tree.
My scenario is a bit different, and I think this safety feature is
highly overrated.  It's not that "I'll never rewind some branches, but
rewind other branches", but rather "I might rewind anything at any
time, but I want immediate information so I can quickly inspect @{1}
to see if that was undesirable".  To put it another way, my philosophy
is not "auto-deny unintended changes", but rather "tell me immediately
about undesirable changes".  To this effect, my prompt looks like:

artagnon|push-current-head=:~/src/git$

The = indicates that I'm in sync with upstream, and that there's
nothing to push.  When I make some changes, that character changes to
, which means that there are ff changes to push.  Finally,
artagnon|push-current-head<>:~/src/git$

has my immediate attention.  <> means that I've diverged from
upstream.  Since the prompt is present all the time, I catch the
divergence just-in-time.  Moreover, I push very frequently resetting
the prompt to = periodically.

So, do you still need this rewinding safety thing?
So what I do is something like this:

git push publish ; git push repo ; git push code
While we can definitely make the UI better for this (maybe push
--multiple?), there is no fundamental change: we have to re-initialize
all the refspecs, connect to the remote via the transport layer and
prepare a packfile to send.  In other words, it's impossible to make
it any faster than what you get with the above.
where....

[remote "publish"]
        url = ssh://gitolite@ra.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
        fetch = +refs/heads/*:refs/heads/*
        push = next
        push = master
        push = maint
        push = debian
        push = +pu
So you're a batched-push person.  And the above makes it clear that
you don't want to explicitly differentiate between a push and push -f
(the +pu thing).  And this assumes that you never create any new
branches (I branch out all the time), otherwise you'd have rules for
refs/heads/*.  Just out of curiosity, do you ever have ref-renaming
requirements (like push = refs/heads/*:refs/heads/tt/*)?  We were
discussing that on another thread, but I haven't found an
implementation I'm happy with yet.

Re: [PATCH] Added guilt.reusebranch configuration option.

From: Theodore Ts'o <tytso@mit.edu>
Date: 2016-06-15 22:57:25

On Thu, May 23, 2013 at 03:22:50PM +0530, Ramkumar Ramachandra wrote:
Theodore Ts'o wrote:
quoted
Right now I do this just by being careful, but if there was an
automatic safety mechanism, it would save me a bit of work, since
otherwise I might not catch my mistake until I do the "git push
publish", at which point I curse and then start consulting the reflog
to back the state of my tree out, and then reapplying the work I had
to the right tree.
My scenario is a bit different, and I think this safety feature is
highly overrated.  It's not that "I'll never rewind some branches, but
rewind other branches", but rather "I might rewind anything at any
time, but I want immediate information so I can quickly inspect @{1}
to see if that was undesirable".
Spekaing of which, what I'd really appreciate is timestamps associated
with the reflog.  That's because the most common time when I've
screwed something up is after doing a "git rebase -i" and so the
reflog has a *huge* number of entries on it, and figuring out which
entry in the reflog is the right one is painful.  If could tell at a
glance when each entry of the reflog was created, it would make it a
lot easier to untangle a tree mangled by git rebase -i.

In practice, it means I waste five minutes carefully inspecting a few
dozen entries on the reflog, so it's not a disaster, although I'm
generally cursing the whole time while I'm trying to untangle the
whole mess.

This issue with reflogs not having timestamps isn't primarily about
rewind safety, BTW; it's just one of the things which make consulting
the reflog painful --- and it's much more likely happens after I screw
up a git rebase -i, generally because of what happens when there's a
merge conflict and then I accidentally fold two commits together
unintentionally.  The times when I've screwed up a non-rewinding
branch and then needed to recover after discovering the problem when I
try to publish said branch are admittedly rare; maybe once or twice
times in the past twelve months.
So, do you still need this rewinding safety thing?
Meh; I don't *need* it.  But then again, I'm an fairly experienced git
user.  The fact that I use guilt without the "guilt/master" safety
feature and have never gotten bitten by it --- in fact I deliberately
publish rewindable branches with a guilt patch series applies speaks
to the fact that I'm pretty experienced at rewindable heads.

The only reason why I suggested it is because I believe it would be
useful for people with less experience, and perhaps it would help make
rewindable branches less scary, and less subject to a lot of the
fearmongering that you see on the blogosphere.
quoted
So what I do is something like this:

git push publish ; git push repo ; git push code
While we can definitely make the UI better for this (maybe push
--multiple?), there is no fundamental change: we have to re-initialize
all the refspecs, connect to the remote via the transport layer and
prepare a packfile to send.  In other words, it's impossible to make
it any faster than what you get with the above.
Sure, and if I cared I'd make a git alias to automate this, instead of
depending on finger macros.
So you're a batched-push person.  And the above makes it clear that
you don't want to explicitly differentiate between a push and push -f
(the +pu thing).  And this assumes that you never create any new
branches (I branch out all the time), otherwise you'd have rules for
refs/heads/*.
I create new branches all the time.  But they are for my own personal
testing purposes.  So it's fairer to say that I rarely *publish* new
branches; I generally stick to the standard set of next, master,
maint, and pu.  And part of that is that even publishing this number
of branches is enough to sometimes confuse the e2fsprogs developers
who are pulling from my tree.

So what I've done in the past is to create a whole bunch of feature
branches, and then merge them into the pu branch, and then only
publish the pu branch.  And I try to get the feature branches cleaned
up as quickly as I have time, so they can appear on the maint or
master/next branches sooner rather than later.
Just out of curiosity, do you ever have ref-renaming
requirements (like push = refs/heads/*:refs/heads/tt/*)?  We were
discussing that on another thread, but I haven't found an
implementation I'm happy with yet.
In general, no, I don't do that, for the reasons stated above --- even
publishing four branches gets to be confusing enough for people who
are looking at my tree.

I'm sure other people and other communities use git differently, so
please insert the standard disclaimer that there's more than one way
to skin a cat.

Regards,

						- Ted

Re: [PATCH] Added guilt.reusebranch configuration option.

From: Ramkumar Ramachandra <hidden>
Date: 2016-06-15 22:57:25

Theodore Ts'o wrote:
Spekaing of which, what I'd really appreciate is timestamps associated
with the reflog.  That's because the most common time when I've
screwed something up is after doing a "git rebase -i" and so the
reflog has a *huge* number of entries on it, and figuring out which
entry in the reflog is the right one is painful.  If could tell at a
glance when each entry of the reflog was created, it would make it a
lot easier to untangle a tree mangled by git rebase -i.
Yeah, I completely agree with this one.  I've wished for the reflog to
be presented in a nicer ui, with humanized timestamps and colors.
Meh; I don't *need* it.  But then again, I'm an fairly experienced git
user.  The fact that I use guilt without the "guilt/master" safety
feature and have never gotten bitten by it --- in fact I deliberately
publish rewindable branches with a guilt patch series applies speaks
to the fact that I'm pretty experienced at rewindable heads.
Oh, and thanks for mentioning guilt: I just learnt about it.
The only reason why I suggested it is because I believe it would be
useful for people with less experience, and perhaps it would help make
rewindable branches less scary, and less subject to a lot of the
fearmongering that you see on the blogosphere.
My message was a critique.  I'm not denying that the feature may be
useful; it's just that we should have a good rationalization of the
usecase and design something carefully.
Sure, and if I cared I'd make a git alias to automate this, instead of
depending on finger macros.
Yes.  My comment was more of question: can --multiple be more than a
for loop written in shell?  If not, is it worth writing?  Are there
enough users?

Junio mentioned pushurl in the other email: if they're perfect
mirrors, won't pushurl suffice?
I create new branches all the time.  But they are for my own personal
testing purposes.  So it's fairer to say that I rarely *publish* new
branches; I generally stick to the standard set of next, master,
maint, and pu.  And part of that is that even publishing this number
of branches is enough to sometimes confuse the e2fsprogs developers
who are pulling from my tree.
Just for contrast: I never keep anything locally.  I publish as much
of my setup as humanly possible so that I'm not tied to one machine.
In general, no, I don't do that, for the reasons stated above --- even
publishing four branches gets to be confusing enough for people who
are looking at my tree.
Just publish different branches to different locations?  Isn't that
why we got triangular workflows?
I'm sure other people and other communities use git differently, so
please insert the standard disclaimer that there's more than one way
to skin a cat.
Ofcourse.  I believe in being all-inclusive, and not dropping a single
feature that has users.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help