git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Best "triangle" workflow setup?

From
Jeff King <peff@peff.net>
Date
May 11, 2017, 23:36 UTC
Message-ID
<20170511233640.ylf4to3hotngh6xe@sigill.intra.peff.net>
In-Reply-To
<CAHd499AvDRH-KZ7piOE=QsVXSpMt0u5jVXUC=7UPnRVLYo-U5Q@mail.gmail.com>
On Thu, May 11, 2017 at 04:23:03PM -0500, Robert Dailey wrote:
Show 19 quoted lines
> On Thu, May 11, 2017 at 3:17 PM, Jeff King <peff@peff.net> wrote:
> > I think you want:
> >
> >   [push]
> >   default = current
> >   [remote]
> >   pushDefault = myfork
> >
> > to make "git push" do what you want. And then generally have branches
> > mark their counterparts on "origin" (which you can do either at creation
> > time, or probably by using "git push -u origin my-topic" when you push
> > them).
> 
> So without the `pushDefault` setting, `current` will default to a
> remote named `origin` if there is no tracking branch set, correct? So
> `pushDefault` is effectively overriding this built-in default? In
> addition, it seems like since this overrides `branch.name.remote`,
> that this effectively makes the remote tracking branch *only* for
> `pull`. Is this a correct understanding?

Right. The general idea of a triangular workflow is that where you pull from is not the same as where you push to. We have branch.*.pushremote if you really wanted to do it on a per-branch basis, but in my experience you almost always want to use "myfork", because you can't push to "origin" in the first place. :)

Show 9 quoted lines
> > This is similar to what I do for my git.git workflow, though I usually
> > have origin/master as the branch's upstream. I.e., I'd create them with:
> >
> >   git checkout -b my-topic origin
> 
> I'm looking through the `git checkout` and `git branch` documentation,
> but I don't see any mention of it being valid to use a remote name as
> the <start-point> parameter (you're using `origin` in the above
> example). Am I misunderstanding? Did you mean origin/my-topic?

Using "origin" there will resolve to "origin/HEAD", i.e., origin/master. So basically I am saying that all of my topic branches are based on master, and if I were to rebase them (for example), I'd want to rebase the whole thing.

If I were to "git pull", they'd also pull from master, which may or may not be what you want (though with pull.rebase, perhaps). I don't generally use "git pull" at all for my git.git workflow.

Show 9 quoted lines
> > And then rebasing always happens on top of master (because "origin"
> > doesn't even have my topic branch at all). If I want to compare with
> > what I've pushed to my fork, I'd use "@{push}".
> 
> Can you explain more about how your rebase chooses master instead of
> your same-named remote tracking branch? Maybe provide some examples of
> your rebase command and respective configuration (unless what you've
> already provided is sufficient). As for @{push}, I haven't used this
> before, so I'll dig in the docs and learn about it.

The default for "git rebase" (if you don't specify a base) is the configured upstream, which in my case is origin/master. Most of my rebasing is "rebase -i" to rewrite bits, so it automatically picks all the commits on my topic branch.

Maybe it would help to set up a trivial example:
  # just a helper to make dummy commits
  commit() { echo "$1" >"$1" && git add "$1" && git commit -m "$1"; }
  # some parent repo
  git init parent
  (cd parent && commit one)
  # and imagine you have a public fork, too
  git clone --bare parent myfork.git
  # and then you have your local clone; in real life this is obviously
  # the only one that would actually be on your machine, but this is a
  # toy example
  git clone parent local
  cd local
  # set up our triangular config
  git remote add myfork ../myfork.git
  git config remote.pushdefault myfork
  git config push.default current
  # now let's try a topic branch
  git checkout -b topic origin
  commit two
  commit three
  # config will show our topic based on origin/master:
  #  [branch "topic"]
  #	remote = origin
  #	merge = refs/heads/master
  less .git/config
  # this should default to all the commits in our topic (i.e., two, three)
  git rebase -i
  # let's imagine upstream makes more commits on master. We can "pull
  # --rebase" to put our work on top
  (cd ../parent && commit four)
  git pull --rebase
  # pushes go to the matching branch on myfork
  git push
  # if you want to see what you haven't pushed yet, you can use @{push}
  commit five
  git log @{push}..
  # likewise, if you wanted to rebase only commits that you've been
  # working on since your last push:
  git rebase -i @{push}
  # Now imagine "origin" picks up your branch...
  (cd ../parent && git fetch ../myfork.git topic:topic)
  # Depending on your project's workflow, you may want to consider that
  # the new base for further development (and never rebase or rewrite
  # any commits that origin has). You do that by re-pointing your
  # @{upstream} config.
  git fetch
  git branch --set-upstream-to=origin/topic topic
  # now a "rebase -i" would show only the commits origin doesn't have
  # (five and six in this case)
  commit six
  git rebase -i

Hopefully that shows off some of the ways you can use the upstream and push config in practice. Some people may not be as excited about the "rebase" default as I am. I spend quite a lot of time at the end of a series sifting through the commits via "rebase -i" and polishing them up. I also test with "git rebase -x 'make test'".

-Peff
Previous: Robert DaileyNext: Robert Dailey
Message 4 of 6 in “Best "triangle" workflow setup?”
  1. Robert DaileyMay 11, 2017
  2. Jeff KingMay 11, 2017
  3. Robert DaileyMay 11, 2017
  4. Jeff KingMay 11, 2017
  5. Robert DaileyMay 12, 2017
  6. Jeff KingMay 13, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.