# How do I copy a branch & its config to a new name?

7 messages from 2017-03-22 to 2017-03-24. Participants: Ævar Arnfjörð Bjarmason, Jeff King, Jonathan Nieder.
Thread: https://gitlist.dev/t/45472

## Ævar Arnfjörð Bjarmason, 2017-03-22 22:46

Subject: How do I copy a branch & its config to a new name?
Message-ID: <CACBZZX7NDa5o1xSu4HgZ4=kG3mx3U6ja7f3E4yAkFOHDsLdMjA@mail.gmail.com>
URL: https://gitlist.dev/e/CACBZZX7NDa5o1xSu4HgZ4%3DkG3mx3U6ja7f3E4yAkFOHDsLdMjA%40mail.gmail.com

```
When I start work on a new series I have e.g. avar/various-tag-2 with
its upstream info set to origin/master.

When I start avar/various-tag-3 just:

    git checkcout -b avar/various-tag-3 avar/various-tag-2

I don't get the correct tracking info. As far as I can tell there's no
way to do this in a single command, either you do:

    git checkout -b avar/various-tag-4 avar/various-tag-3 && git
branch --set-upstream-to origin/master

Or:

    git checkout -b avar/various-tag-3 -t origin/master && git reset
--hard avar/various-tag-2

But both of these are really just a limited special case for what I'd
really like, which is given branch "foo", copy it and all its
configuration to a new name "bar". I.e. both of the hacks above only
set up the correct tracking info, but none of the other branch.*
variables I may have set.

So I have this relative horror-show as an alias:

    $ git config alias.cp-branch
    !f() { git checkout -b $2 $1 && for line in $(git config --list
--file .git/config | grep "^branch\.$1"); do key=$(echo $line | cut
-d= -f1); newkey=$(echo $key | sed "s!$1!$2!"); value=$(echo $line |
cut -d= -f2); git config $newkey $value; done; }; f

Turned into a more readable tiny shell-script you can call git-cp-branch that's:

    #!/bin/sh -e
    git checkout -b $2 $1
    for line in $(git config --list --file $(git rev-parse
--git-dir)/config | grep "^branch\.$1");
    do
        key=$(echo $line | cut -d= -f1)
        newkey=$(echo $key | sed "s!$1!$2!")
        value=$(echo $line | cut -d= -f2)
        git config $newkey $value
    done

I couldn't find any previous list discussion about this, but if not I
think something like:

    git [checkout|branch] --copy src dest

Would make sense as an interface for this.

```

## Jeff King, 2017-03-22 22:58

Subject: Re: How do I copy a branch & its config to a new name?
Message-ID: <20170322225800.3h2mnnmmj2hbo36c@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20170322225800.3h2mnnmmj2hbo36c%40sigill.intra.peff.net
In-Reply-To: <CACBZZX7NDa5o1xSu4HgZ4=kG3mx3U6ja7f3E4yAkFOHDsLdMjA@mail.gmail.com>

```
On Wed, Mar 22, 2017 at 11:46:14PM +0100, Ævar Arnfjörð Bjarmason wrote:

> But both of these are really just a limited special case for what I'd
> really like, which is given branch "foo", copy it and all its
> configuration to a new name "bar". I.e. both of the hacks above only
> set up the correct tracking info, but none of the other branch.*
> variables I may have set.

I thought that's what "git branch -m" was for, though I don't know how
thorough it is about finding config that refers _to_ your branch (I know
it handles config _for_ your branch).

There might be room for improvement there.

-Peff

```

## Ævar Arnfjörð Bjarmason, 2017-03-22 23:54

Subject: Re: How do I copy a branch & its config to a new name?
Message-ID: <CACBZZX47euh-K8-DUjDKr6i=g8MzmivOzA5fFTyPQjZhkzM2uA@mail.gmail.com>
URL: https://gitlist.dev/e/CACBZZX47euh-K8-DUjDKr6i%3Dg8MzmivOzA5fFTyPQjZhkzM2uA%40mail.gmail.com
In-Reply-To: <20170322225800.3h2mnnmmj2hbo36c@sigill.intra.peff.net>

```
On Wed, Mar 22, 2017 at 11:58 PM, Jeff King <peff@peff.net> wrote:
> On Wed, Mar 22, 2017 at 11:46:14PM +0100, Ævar Arnfjörð Bjarmason wrote:
>
>> But both of these are really just a limited special case for what I'd
>> really like, which is given branch "foo", copy it and all its
>> configuration to a new name "bar". I.e. both of the hacks above only
>> set up the correct tracking info, but none of the other branch.*
>> variables I may have set.
>
> I thought that's what "git branch -m" was for, though I don't know how
> thorough it is about finding config that refers _to_ your branch (I know
> it handles config _for_ your branch).
>
> There might be room for improvement there.

-m can only rename "foo" -> "bar", but I'd like to end up with a new
"bar" with the same config as "foo"

```

## Jeff King, 2017-03-22 23:57

Subject: Re: How do I copy a branch & its config to a new name?
Message-ID: <20170322235754.wver7y6hpfyotwzg@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20170322235754.wver7y6hpfyotwzg%40sigill.intra.peff.net
In-Reply-To: <CACBZZX47euh-K8-DUjDKr6i=g8MzmivOzA5fFTyPQjZhkzM2uA@mail.gmail.com>

```
On Thu, Mar 23, 2017 at 12:54:48AM +0100, Ævar Arnfjörð Bjarmason wrote:

> On Wed, Mar 22, 2017 at 11:58 PM, Jeff King <peff@peff.net> wrote:
> > On Wed, Mar 22, 2017 at 11:46:14PM +0100, Ævar Arnfjörð Bjarmason wrote:
> >
> >> But both of these are really just a limited special case for what I'd
> >> really like, which is given branch "foo", copy it and all its
> >> configuration to a new name "bar". I.e. both of the hacks above only
> >> set up the correct tracking info, but none of the other branch.*
> >> variables I may have set.
> >
> > I thought that's what "git branch -m" was for, though I don't know how
> > thorough it is about finding config that refers _to_ your branch (I know
> > it handles config _for_ your branch).
> >
> > There might be room for improvement there.
> 
> -m can only rename "foo" -> "bar", but I'd like to end up with a new
> "bar" with the same config as "foo"

Ah, I see. You really want "copy". In that case, yeah, I think you'd
need a new command. It might make sense for it to share implementation
with rename (and just do the "add new config" part, skipping the "drop
old config" half).

-Peff

```

## Jonathan Nieder, 2017-03-24 00:52

Subject: Re: How do I copy a branch & its config to a new name?
Message-ID: <20170324005249.GF20794@aiede.mtv.corp.google.com>
URL: https://gitlist.dev/e/20170324005249.GF20794%40aiede.mtv.corp.google.com
In-Reply-To: <CACBZZX7NDa5o1xSu4HgZ4=kG3mx3U6ja7f3E4yAkFOHDsLdMjA@mail.gmail.com>

```
Hi,

Ævar Arnfjörð Bjarmason wrote:

> I couldn't find any previous list discussion about this, but if not I
> think something like:
>
>     git [checkout|branch] --copy src dest
>
> Would make sense as an interface for this.

Sounds good to me. :)

Thanks,
Jonathan

```

## Ævar Arnfjörð Bjarmason, 2017-03-24 11:10

Subject: Re: How do I copy a branch & its config to a new name?
Message-ID: <CACBZZX6U0PAAK8vJxBW2VSzbtfttFUNTZhDGk=BzLxkaTn64gw@mail.gmail.com>
URL: https://gitlist.dev/e/CACBZZX6U0PAAK8vJxBW2VSzbtfttFUNTZhDGk%3DBzLxkaTn64gw%40mail.gmail.com
In-Reply-To: <20170324005249.GF20794@aiede.mtv.corp.google.com>

```
On Fri, Mar 24, 2017 at 1:52 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Hi,
>
> Ęvar Arnfjörš Bjarmason wrote:
>
>> I couldn't find any previous list discussion about this, but if not I
>> think something like:
>>
>>     git [checkout|branch] --copy src dest
>>
>> Would make sense as an interface for this.
>
> Sounds good to me. :)

Actually this is a bit confusing, but I think reversing the arguments
makes sense, i.e.:

    git branch -c dest [src]

And similarly:

    git checkout -c dest [<src>]

This is confusing in that it reverses the arguments, but more useful
in that it allows you to omit src like the other invocations of these
commands, and you can e.g. do:

    git branch -c avar/topic-2

While on avar/topic to start working on avar/topic-2, which would copy
avar/topic's state & config.

I'll put this on my TODO list, but unless someone comes up with a
compelling argument against the above I plan to make the interface
look like that.

```

## Jeff King, 2017-03-24 21:17

Subject: Re: How do I copy a branch & its config to a new name?
Message-ID: <20170324211701.vvmp6n4c77o2dvbz@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20170324211701.vvmp6n4c77o2dvbz%40sigill.intra.peff.net
In-Reply-To: <CACBZZX6U0PAAK8vJxBW2VSzbtfttFUNTZhDGk=BzLxkaTn64gw@mail.gmail.com>

```
On Fri, Mar 24, 2017 at 12:10:49PM +0100, Ævar Arnfjörð Bjarmason wrote:

> Actually this is a bit confusing, but I think reversing the arguments
> makes sense, i.e.:
> 
>     git branch -c dest [src]
> 
> And similarly:
> 
>     git checkout -c dest [<src>]
> 
> This is confusing in that it reverses the arguments, but more useful
> in that it allows you to omit src like the other invocations of these
> commands, and you can e.g. do:
> 
>     git branch -c avar/topic-2
> 
> While on avar/topic to start working on avar/topic-2, which would copy
> avar/topic's state & config.
> 
> I'll put this on my TODO list, but unless someone comes up with a
> compelling argument against the above I plan to make the interface
> look like that.

I think it probably should match "git branch -m", which uses:

  git branch -c [<oldbranch>] <newbranch>

That's the closest operation we currently have, and it still allows
omitting the src. It _is_ different than:

  git branch <branchname> [<start-point>]

I wondered if you could advertise "-c" not as a new "copy mode", but
rather as an option for normal branch creation. Sort of a "by the way,
copy the config". But I don't think that's a great mental model.
<start-point> doesn't have to be a branch at all.

-Peff

```
