On Thu, May 11, 2017 at 04:23:03PM -0500, Robert Dailey wrote: > On Thu, May 11, 2017 at 3:17 PM, Jeff King <peff@xxxxxxxx> 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. :) > > 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. > > 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