新しい(そして空の!)「ルート」ブランチを作成する方法は?


135

このgitリポジトリに新しい「ルート」ブランチを定義したいと思います。「ルート」ブランチとは、リポジトリ内の他のすべてのブランチから完全に独立しているブランチを意味します1

残念ながら、Aリポジトリのコミットツリーの最下部にあるコミット(これをと呼びましょう)にも多くのファイルが含まれています(これは、かなり成熟したプロジェクトで初期化されたリポジトリでした)。

これは、私がA新しいブランチとして指定したとしても<start-point>、この新しいブランチは「白紙の状態」から始まるのではなく、でコミットされたすべてのファイルが含まれることを意味しますA

このリポジトリにできる限り<start-point>近い状態で完全に裸のブランチを作成する方法はありますAか?


1ところで、これは新しいリポジトリを作成することと同じではありません。別々のリポジトリは、多くの理由で便利ではありません。


編集:OK、これはvcsjonesの答えに基づいて私がしたことです:

# save rev of the current earliest commit
OLDBASE=$(git rev-list --max-parents=0 HEAD)

# create a new orphan branch and switch to it
git checkout --orphan newbranch
# make sure it's empty
git rm -rf .

# create a new empty commit in the new branch, and
# save its rev in NEWBASE
git commit --allow-empty -m 'base commit (empty)'
NEWBASE=$(git rev-list HEAD)

# specify $NEWBASE as the new parent for $OLDBASE, and
# run filter-branch on the original branch
echo "$OLDBASE $NEWBASE" > .git/info/grafts
git checkout master
git filter-branch

# NOTE: this assumes that the original repo had only one
# branch; if not, a git-filter-branch -f <branch> command
# need to be run for each additional branch.

rm .git/info/grafts

この手順は少し複雑ですが、最終結果は空のベースコミットであり<start-point>、新しい「白紙の状態のブランチ」のとして機能できます。そのとき私がしなければならないのは、

git checkout -b cleanslate $(git rev-list --max-parents=0 HEAD)

将来的には、常に次のような新しいリポジトリを作成します。

git init
git commit --allow-empty -m 'base commit (empty)'

...したがって、最初のコミットはであり、新しい独立したブランチを開始するために常に使用できます。(これは、ごくまれに必要な機能ですが、すぐに利用できるようにするのは非常に簡単です。)



1
@Anonymoose:記録のためだけに(議論ではなく):私はあなたの意見に同意しません。
kjo

1
基づくはるかに簡単な解決策があるようですgit rebase --onto、見stackoverflow.com/questions/645450/...
ステフェイン・グーリッホン

回答:


223

--orphanブランチを作成するときに使用します。

git checkout --orphan YourBranchName

これにより、コミットがゼロの新しいブランチが作成されますが、すべてのファイルがステージングされます。その時点で、それらを削除することができます。
(「それらを削除する」:A git reset --hardはインデックスを空にし、空の作業ツリーを残します)

--orphanの詳細については、チェックアウトのmanページご覧ください


これは本質的に白紙の状態を作りますか?まるで、ゼロから?それとも以前のすべての変更を保持しますが、gitの履歴には残りませんか?
Con Antonakos

4
@ConAntonakosこれは、親なしで新しいブランチを作成します。他のブランチは影響を受けず、変更はすべて保持されます。
fuz

11

受け入れられた回答に追加するには- クリーンな状態に戻すためのベストプラクティスは、後からブランチを設定するときに簡単にリベースできるように、最初の空のコミットを作成することです。さらに、クリーンな状態が必要なため、おそらくコミットしてはいけないファイルがコミットされているので、それらをインデックスから削除する必要があります。これらを念頭に置いて、次のことを行う必要があります。

$ git checkout --orphan dev2
Switched to a new branch 'dev2'
$ git reset # unstage all the files, you probably don't want to commit all of them
$ git commit --allow-empty -m 'Initial empty commit'
[dev2 (root-commit) a515c28] Initial empty commit

1
rootにリベースできるので、2012年の時点ではこれは必要ないと思います。
Timmmm


1

このリポジトリに完全に裸のブランチを作成する方法はありますか?

使用する実際のコマンド(Git 2.28以降)は次のとおりです。

git switch --discard-changes --orphan newBranch
# or
git switch -f --orphan newBranch

git switchはGit 2.23(2019年8月)から利用可能で、古い混乱を招くgit checkoutコマンドを置き換えます。

ただし、Git 2.28(2020年第3四半期)をお勧めしますgit switch --discard-changes --orphan。これは、そのバージョンで最適化されているためです。

commit 8d3e33dcommit 8186128(2020年5月21日)のbrian mをbk2204参照してくださいカールソン(
(合併によりJunio C浜野- gitster-ded44afコミット 2020年6月9日)

builtin/checkout:メタデータの初期化を簡素化

サインオフ:brian m。カールソン
レビュー担当者:Derrick Stolee

電話init_checkout_metadataするときreset_tree,我々はそれがフィルタに渡すことができるように、質問にコミットしていない、またはツリーは、何のコミットがある場合のオブジェクトIDを渡したいです。

この後者のケースは、チェックアウトコードの他の場所で発生する可能性があると予想していましたが、ここでは発生しません。

commitオブジェクトがない唯一のケースはgit switch--orphan

さらに、このコードパスをヒットできるのは、--forceまたはのいずれかを使用したコミットオブジェクトがない場合のみ--discard-changesです。

このような場合、チェックアウトメタデータをコミットまたはツリーで初期化しても意味がありません。

  • (a)コミットはなく、空のツリーのみであり、
  • (b)ファイルのないブランチをチェックアウトするときにファイルが汚されないため、データを使用しません。

この場合、すべてゼロのオブジェクトIDを渡します。有効なポインターである値が必要なだけだからです。

テスト:

git switch master
echo foo >foo.txt
git switch --discard-changes --orphan new-orphan2
git ls-files >tracked-files
# test_must_be_empty tracked-files
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.