ローカルとリモートの両方のGitリポジトリのマスターブランチの名前を変更する


821

masterリモートブランチを追跡するブランチがありますorigin/master

それらの名前をmaster-oldローカルとリモートの両方に変更したいと思います。これは可能ですか?

追跡したorigin/master(そしてをmaster介してローカルブランチを常に更新したgit pull)他のユーザーの場合、リモートブランチの名前を変更するとどうなりますか?
彼らはgit pullまだ動くのでしょうか、それともそれがorigin/masterもう見つけられなかったというエラーを投げるでしょうか?

次に、さらにmaster(ローカルとリモートの両方で)新しいブランチを作成します。繰り返しますが、これを実行した後、他のユーザーが実行するとgit pullどうなりますか?

こうなると大変なことになると思います。私が欲しいものを手に入れるためのきれいな方法はありますか?それとも、そのままにmasterして新しいブランチmaster-newを作成し、そこでさらに作業するだけですか?


2
受け入れられた回答で与えられたレシピはどの名前のブランチにも適用されますが、(デフォルトで)Gitのマスターブランチの(特別な)特別な役割のため、警告(上記のとおり)は適用されません。
kynan 2012

3
@kynan:分からないと思います。マスターに適用され、他のブランチには適用されない注意事項は何ですか?それがxyという名前のブランチであり、他の人がそのブランチを追跡している場合、それはどのように違うのでしょうか?
アルバート

4
通常はリモートマスターを削除できないことに注意してください。これはアリストテレスの回答には当てはまりません。そのため、それを受け入れられた回答としてマークすることができます。正解です。リモートトラッキングブランチからgit push -fの機能に影響がありますpull
kynan 2012

master-old前のmasterブランチと同じコミットを指す新しいブランチを作成できます。次に、戦略を使用して、masterブランチを新しい変更で上書きできます。リモートで早送り以外の変更が許可されていない場合は、マージを実行できます。また、他のユーザーが強制的に更新することもありません。mergeours
dnozay 2014年

1
@kynan masterは、既存の唯一のブランチである限り、特別なものです。複数のブランチがあるとすぐに、すべてのブランチが同じ立場になります。
jub0bs 2014

回答:


615

名前の変更に最も近いのは、リモートで削除してから再作成することです。例えば:

git branch -m master master-old
git push remote :master         # delete master
git push remote master-old      # create master-old on remote

git checkout -b master some-ref # create a new local master
git push remote master          # create master on remote

ただし、これには多くの注意事項があります。まず、既存のチェックアウトは名前変更を認識しませ -gitはブランチの名前変更を追跡しませ。新しいmasterものがまだ存在しない場合、git pullはエラーになります。新しいものmasterが作成された場合。プルは、マージしようとしますmastermaster-old。そのため、以前にリポジトリをチェックアウトしたことがあるすべての人の協力がない限り、一般的には悪い考えです。

注:新しいバージョンのgitでは、デフォルトでリモートでマスターブランチを削除できません。あなたは、設定することによって、これをオーバーライドすることができますreceive.denyDeleteCurrentし、設定値をwarnまたはignoreリモートリポジトリ。そうでなければ、あなたは、すぐに新しいマスターを作成スキップする準備が整いました場合にはgit push remote :masterステップをし、合格--forcegit push remote masterのステップ。リモートの設定を変更できない場合、マスターブランチを完全に削除することはできません。

この警告は、現在のブランチ(通常はmasterブランチ)にのみ適用されます。他のブランチは、上記のように削除して再作成できます。


2
ブランチは単なる(名前、ハッシュ)ペアです-それ以上、それ以下ではありません。ブランチにはreflogがありますが、これはリモートクライアントには公開されません。
bdonlan 2009年

122
リモートでマスターを削除する前に、リモートでマスターを作成します。私はただの妄想です。
Adam Dymitruk、2010

6
以下のアリストテレスの回答では、マスターを削除せずにこれを行うことができるので、私はそれが望ましいと思います。
クレイブリッジ

13
/の代わりにnew-branch-nameand を使用できる場合、それは明確で安全であるため、これは一般的な問題です。old-branch-namemastermaster-old
Jaider 2012

2
削除されたブランチ(ここでは:マスター)が他のブランチによって参照されていない場合、gitはそのすべてのコミットをガベージコレクションする可能性があります。–一部のgit porcelainコマンドは、ガベージコレクションをトリガーします。–したがって、最初に新しい名前を作成し(同じコミットを指す)、次に古い名前を削除します。
Robert Siemer、2015年

257

あなたが現在いると仮定するとmaster

git push origin master:master-old        # 1
git branch master-old origin/master-old  # 2
git reset --hard $new_master_commit      # 3
git push -f origin                       # 4
  1. まず、ローカルリポジトリのコミットに基づいてmaster-oldoriginリポジトリにブランチを作成しmasterます。
  2. この新しいorigin/master-oldブランチの新しいローカルブランチを作成します(これは自動的に追跡ブランチとして適切に設定されます)。
  3. ここで、ローカルmasterが指すコミットを指定します。
  4. 最後に、新しいローカルを反映するようにリポジトリを強制的に変更masteroriginますmaster

(他の方法で行う場合master-oldは、が正しく追跡されるように設定するために、少なくとももう1つの手順が必要origin/master-oldです。この記事の執筆時に投稿された他のソリューションには、それが含まれていません。)


11
これは「答え」よりも良い答えだと思いますが、ブランチに名前を変更するためにここに来た人(明示的にマスターではない)にとって、3番目のステップはあまり意味がありません。
knocte

それがあなたのmasterブランチであるか別のブランチであるかにかかわらず、それは答えに全く違いを生じさせません。質問のタイトルはひどいものでしたが、ブランチの名前を変更するだけでなく、より複雑なタスクについて尋ねられます。
アリストテレスPagaltzis 2012

3
これが私にとって有効な解決策であることがわかりました。masterを別のブランチに置き換えようとしました。私はgit log -1 origin / what_i_want_as_new_masterを実行して、ステップ3の$ new_master_commitを取得しました。プッシュ(ステップ4)の後、他の開発者は「ブランチが295コミットでマスターよりも進んでいます」というメッセージをプルして取得します。これを修正するために、実行ごとに通知するメールを送信しました。git pull; git checkout some_random_branch; gitブランチ-Dマスター; git pull; git checkout master; 基本的に、ローカルマスターを削除して新しいバージョンをプルする必要があります。そうしないと、ローカルの間違った場所にいます。
nairbv 2013年

あなたははるかに簡単にmasterそれを行うことができたでしょう:彼らがすでにオンになっていると仮定すると、彼らはgit fetch && git reset --hard origin/master自分のローカルmasterをのものと同じに強制することができoriginます。これと、master保持したいローカルコミットが存在するより複雑なケースを、stackoverflow.com
q / 4084868でドキュメント化しました

リモート構成ファイルに「denyNonFastforwards = false」が含まれていることを確認してください。そうでないと、「リモート:エラー:非高速転送refs / heads / masterを拒否します(最初にプルする必要があります)」
gjcamann

160

Git v1.7では、これが少し変わったと思います。ローカルブランチの追跡参照を新しいリモートに更新するのが非常に簡単になりました。

git branch -m old_branch new_branch         # Rename branch locally    
git push origin :old_branch                 # Delete the old branch    
git push --set-upstream origin new_branch   # Push the new branch, set local branch to track the new remote

10
代わるものは--set-upstream次のとおりです。あなたはあなたのブランチがローカルに名前を変更し、原点を削除したら、単純に実行します git push -u --all
lucifurious

4
gitではリモートマスターを削除できないため、これはマスターブランチでは機能しません。
Alexandre Neto 2014年

4
@AlexandreNetoこの場合、2行目の前に3行目を実行し、デフォルトのブランチをに設定しnew_branchて、最終的masterに2行目のリモートを削除できます。
Tristan Jahier、2015

3
驚くほど簡単な手順。これが質問の最良の答えです
siddhusingh

13
リモートブランチを削除するgit push origin --delete old_branch方が少し読みやすくなります。
ThomasW 2015年

35
git checkout -b new-branch-name
git push remote-name new-branch-name :old-branch-name

new-branch-name削除する前に手動で切り替えなければならない場合がありますold-branch-name


このソリューションの一部は、ローカルの古いブランチ名を削除しますか、それとも別の演習ですか?
GreenAsJade 2013

4
最後にgit branch -d old-branch-nameローカルの古いブランチを削除するために実行する必要があると思います。
Nabi KAZ

1つのコマンドのみで変更をプッシュできますgit push remote-name new-branch-name :old-branch-name
sigod 2014年

この方法でgitの履歴を複雑にすることはありませんか?代わりに、現在のブランチの名前を変更するだけで、新しいブランチを開きます。
androidevil 2014年

1
@androiderいいえ。gitのブランチは単純な参照です。
sigod 2014年

29

ブランチの名前を変更する方法はたくさんありますが、私はより大きな問題に焦点を当てます。「クライアントが早送りして、ブランチをローカルで混乱させる必要がないようにする方法」です。

まず簡単な画像: マスターブランチの名前を変更し、クライアントが早送りできるようにする

これは実際には簡単なことです。しかし、それを乱用しないでください。アイデア全体はマージコミットにかかっています。それらは早送りを可能にし、ブランチの履歴を別のブランチとリンクします。

ブランチの名前を変更する:

# rename the branch "master" to "master-old"
# this works even if you are on branch "master"
git branch -m master master-old

新しい「マスター」ブランチを作成します。

# create master from new starting point
git branch master <new-master-start-point>

親子履歴を持つマージコミットを作成します。

# now we've got to fix the new branch...
git checkout master

# ... by doing a merge commit that obsoletes
# "master-old" hence the "ours" strategy.
git merge -s ours master-old

そして出来上がり。

git push origin master

これは、mergeコミットを作成すると、ブランチを新しいリビジョンに早送りできるため機能します。

賢明なマージコミットメッセージを使用する:

renamed branch "master" to "master-old" and use commit ba2f9cc as new "master"
-- this is done by doing a merge commit with "ours" strategy which obsoletes
   the branch.

these are the steps I did:

git branch -m master master-old
git branch master ba2f9cc
git checkout master
git merge -s ours master-old

3
ありがとう!git merge -s ours master-old他の答えが見逃している重要な部分です。また、「簡単にできる」とは、「理解しやすい、または見つけやすい」という意味ではなく、gitの多くに当てはまるように見えますが、私は余談です。
Martin Vidner、2016

3
削除について言及されていないこと、および上流のクローンを操作するユーザーの移行が「シームレス」であるという事実が気に入っています。ありがとうございました!
ピオトレック2016年

12

前の質問と同じ状況についてまだ質問していると思います。つまり、master-newの履歴にはmaster-oldは含まれません。* master-new "master"を呼び出すと、事実上、履歴が書き換えられます。マスターが以前のマスターの位置の子孫ではない状態にどのように入るは関係ありません。単にその状態にあるということです。

マスターが存在しないときにプルしようとする他のユーザーは、プルが失敗するだけで(リモートでのそのような参照はありません)、新しい場所に再び存在すると、プルはマスターを新しいリモートマスターとマージしようとする必要があります。まるでリポジトリのmaster-oldとmaster-newをマージしたかのように。ここで何をしようとしているのかを考えると、マージには競合があります。(それらが解決され、結果がリポジトリに戻された場合、両方のバージョンの履歴があるため、さらに悪い状態になります。)

質問に簡単に答えるには、歴史に間違いがあることを受け入れる必要があります。これは大丈夫です。それは誰にでも起こります。git.gitリポジトリに元に戻されたコミットがあります。重要なことは、ひとたび歴史を公開すれば、誰もが信頼できるものになるということです。

*そうした場合、これはいくつかの変更をマスターにプッシュしてから、以前の場所に新しいブランチを作成することと同じです。問題ない。


ええ、それは同じ問題です、それを解決する方法の1つのアイデアでした。しかし、私がこのブランチの名前変更を行わなくても、それが可能であるかどうかは興味深いものでした。「マスター」などの参照は、特定のコミットへの参照にすぎないと思いました。私は本当に歴史を変えたくありません。マスター参照を別のヘッドに向けるだけだと思っていました。これはまた、以前に使用したことがあるブランチ名を再び使用することはできないことを意味します。
アルバート

実際、ブランチは参照、つまりコミットへのポインタです。問題は、ブランチのヘッドが特定の方法(つまり、常に早送り)で進化することを期待することです。他の誰かの観点から見ると、公開リポジトリ内のブランチを移動することは、ブランチの履歴を書き換えることと同じです。これまで使用していたすべてを含むコミットを指すことはありません。
Cascabel、

8

選択した答えは、私はそれをしようとしたときに失敗しました。エラーがスローされますrefusing to delete the current branch: refs/heads/master。私は私のために働くものを投稿すると思います:

git checkout master             # if not in master already

git branch placeholder          # create placeholder branch
git checkout placeholder        # checkout to placeholder
git push remote placeholder     # push placeholder to remote repository

git branch -d master            # remove master in local repository
git push remote :master         # remove master from remote repository.

トリックは、リモートリポジトリにプッシュする直前にプレースホルダーにチェックアウトすることです。残りは自明であり、masterブランチを削除してリモートリポジトリにpushすると、動作するようになります。ここから抜粋。


これがリモート側でチェックされていると、git push remote:masterで失敗します-エラーログ行のプレフィックスとして「remote:error:」が表示されます。
rafalmag 2015

2

良い。私の2セント。サーバーにログインし、gitディレクトリに移動して、ベアリポジトリのブランチの名前を変更するのはどうですか。これには、同じブランチの再アップロードに関連するすべての問題があるわけではありません。実際、「クライアント」は変更された名前を自動的に認識し、リモート参照を変更します。その後(または前)に、ブランチのローカル名を変更することもできます。


8
githubサーバーにログオンするための資格情報を忘れました。資格証明を持っている人:-P
ダニエルフィッシャーレニーベーコン2013

1

何について:

git checkout old-branch-name
git push remote-name new-branch-name
git push remote-name :old-branch-name
git branch -m new-branch-name

ブランチの追跡を台無しにする-ユーザーはブランチをローカルで修正する必要があるかもしれませんか?
dnozay 2016年

1

これは私が知っている最も簡単で最も「読みやすい」方法です:

-mを使用してローカルブランチを「移動」する

git branch -m my_old_branch_name my_new_branch_name

'moved'ブランチをリモートにプッシュし、-uを使用して 'upstream'を設定します。

git push origin -u my_new_branch_name

(「アップストリーム」を設定すると、基本的にローカルブランチがリモートに「接続」され、フェッチ、プル、プッシュなどが機能します)

リモートから古いブランチを削除する

git push origin -D <old_name>

(ローカルブランチは既に削除されています。最初のステップでブランチを「移動」したためです)


1

OKローカルリモートの両方ブランチの名前を変更するのはとても簡単です!...

あなたがブランチにいるなら、あなたは簡単に行うことができます:

git branch -m <branch>

そうでない場合は、次のことを行う必要があります。

git branch -m <your_old_branch> <your_new_branch>

次に、削除を次のようにリモートにプッシュします。

git push origin <your_old_branch>

これで完了です。プッシュしようとしたときにアップストリームエラーが発生した場合は、次のようにしてください。

git push --set-upstream origin <your_new_branch>

以下の画像も作成して、実際のコマンドラインで手順を示します。手順に従うだけで問題ありません。

ここに画像の説明を入力してください


0

以下を実行できます。

git -m master master-old #rename current master
git checkout -b master   #create a new branch master
git push -f origin master #force push to master

しかし、他の人がこのリポジトリを共有している場合、強制プッシュは悪い考えです。強制プッシュを行うと、変更履歴が新しい履歴と競合します。


0

ジョブを実行するために、以下をシェルスクリプトに保存できます。

例えば:

remote="origin"

if [ "$#" -eq 0 ] # if there are no arguments, just quit
then
    echo "Usage: $0 oldName newName or $0 newName" >&2
    exit 1
elif
    [ "$#" -eq 1 ] # if only one argument is given, rename current branch
then 
    oldBranchName="$(git branch | grep \* | cut -d ' ' -f2)" #save current branch name
    newBranchName=$1
else
    oldBranchName=$1
    newBranchName=$2
fi

git branch -m $oldBranchName $newBranchName

git push $remote :$oldBranchName #delete old branch on remote
git push --set-upstream $remote $newBranchName # add new branch name on remote and track it

ここで、デフォルトのリモート名「origin」はハードコーディングされていることに注意してください。構成可能な場合は、スクリプトを拡張して作成できます。

次に、このスクリプトをbashエイリアス、gitエイリアス、またはsourcetreeカスタムアクションなどで使用できます。


-1

私は、キーはあなたが実行しているという認識であると考えているダブル:名前変更をmasterするmaster-oldともmaster-newmaster

他のすべての答えから私はこれを合成しました:

doublerename master-new master master-old

最初にdoublerenameBash関数を定義する必要があります。

# doublerename NEW CURRENT OLD
#   - arguments are branch names
#   - see COMMIT_MESSAGE below
#   - the result is pushed to origin, with upstream tracking info updated
doublerename() {
  local NEW=$1
  local CUR=$2
  local OLD=$3
  local COMMIT_MESSAGE="Double rename: $NEW -> $CUR -> $OLD.

This commit replaces the contents of '$CUR' with the contents of '$NEW'.
The old contents of '$CUR' now lives in '$OLD'.
The name '$NEW' will be deleted.

This way the public history of '$CUR' is not rewritten and clients do not have
to perform a Rebase Recovery.
"

  git branch --move $CUR $OLD
  git branch --move $NEW $CUR

  git checkout $CUR
  git merge -s ours $OLD -m $COMMIT_MESSAGE

  git push --set-upstream --atomic origin $OLD $CUR :$NEW
}

これはgit rebase、ブランチの内容がまったく異なるという点で履歴の変更と似ていますが、クライアントがを使用しても安全に早送りできるという点が異なりますgit pull master


-5
git update-ref newref oldref
git update-ref -d oldref newref

2
これは私にはうまくいかないようです、私は得ます:git update-ref trunk trunk2 fatal:trunk2:not a valid SHA1
Gregg Lind
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.