4

In this post, I found out that it was possible to create individual mappings for branch names so that pushing back to a central repository can be permanently mapped to a subtree, like:

  • git master branch name: foo
  • remote branch name: foo
  • git push origin foo on slave1 does the equivalent of git push origin foo:refs/slave1/foo

But the post implied that it's not possible to do this on an automatic basis, e.g. specifying a wildcard map from refs/heads/* on the remote to refs/slave1/* on the master.

Well, is it possible?

I clone my repository in a ton of places, make changes on my devbox, and fetch those changes to the copy on the development server for testing. I end up making changes on the dev server and wanting to push them back, but I can't push it with the same branch name because I have that branch checked out on the master. It would be nice to just configure the clone once to be smart about it.

If it's not possible, this is a feature request and I'm pasting this URL to the git mailing list :)

Community
  • 1
  • 1
joshk0
  • 2,574
  • 2
  • 25
  • 36
  • 1
    The word "subtree" is maybe not the best choice - that has specific meaning in git (since its internal object structure includes trees containing trees and blobs). What you're talking about is commonly referred to as ref namespaces, though it is implemented as a subtree of the refs directory structure (until the refs get packed, anyway). – Cascabel Apr 19 '10 at 21:53
  • Will be referenced locally as `remotes/origin/refs/slave1/foo`. – Brent Bradburn Aug 16 '17 at 05:23

2 Answers2

2

I found the answer myself.

git config --add remote.origin.push +refs/heads/*:refs/MACHINENAME/*

joshk0
  • 2,574
  • 2
  • 25
  • 36
  • This didn't work for me when pushing to a GitHub-hosted repository. Well, when I say "didn't work," I mean that _git push_ succeeded, but GitHub does not display that new branch anywhere. Perhaps GitHub is storing these branch references elsewhere, so that your `refs/MACHINENAME` prefix doesn't match where GitHub is looking. – seh Feb 27 '20 at 15:12
  • 1
    @seh This doesn't work because the refspec is incorrect. It should be `refs/heads/*:refs/heads/MACHINENAME/*`. Github will only show refs under `refs/heads`, which is why you don't see it upstream. Also please avoid the `+` in front of the refspec unless you know what you are doing. This basically makes the push a force-push (same as putting the `--force` option). – void.pointer Mar 11 '20 at 14:41
  • Thank you, @void.pointer. I'll try your suggestion with my next push attempt. (And I had left the `+` off in my experiment, being wary of forcing more often than necessary.) – seh Mar 12 '20 at 00:27
  • Including the _heads_ component worked as intended. Thanks again. – seh Mar 14 '20 at 00:46
  • It's still not possible to push HEAD only with it - it will push all local branches instead (given you didn't set branch to push explicitly) – bam Apr 04 '21 at 21:44
1

The command in the accepted answer will force push every branch in the local repo to the remote, which is not quite what I wanted when I found this post. Here's an adaptation that worked for me.

Prefixed Push

To push only the current branch (without forcing) while adding a prefix, I made a "prefixed push" alias:

git config --global --add alias.ppush '!git push -u origin "HEAD:refs/heads/PREFIX/$(git rev-parse --abbrev-ref HEAD)"'

where I replace PREFIX with my desired prefix string. Now I can say git ppush when I want to push the current branch while adding the prefix.

I use this when I want to prefix all my branches with my username, so that I can tell it apart from other people's branches while working in a shared repository. In situations where I don't want to add a prefix, I can still use the regular git push.

Mixing push and ppush

If I start out with git ppush and later switch to git push, Git's default behavior is to complain because the local and remote branches will not have the same name (one has a prefix and the other does not). To avoid this, I ended up also configuring push.default:

git config --global --add push.default upstream

With this configured, I can use ppush when pushing my branch for the first time, and then switch to the regular push for subsequent updates.

Tom Baldwin
  • 978
  • 7
  • 9