4

ちょっと変ですが、gitではかなり一般的な操作を実行できません。基本的に私が欲しいのは、機能ブランチをチェックアウトすることです。ヘッドを使用するのではなく、SHAIDを使用します。このSHAは、マスターブランチからのマージを指します。

問題は、機能ブランチからのコミットなしで、マスターブランチだけを取得することです。現在、マスターブランチで以前に導入されたリグレッションを修正しようとしています。

よりわかりやすくするために、問題のあるリポジトリを再作成するための小さなbashスクリプトを作成しました。

#!/bin/bash

rm -rf ./.git
git init

echo "test1" > test1.txt
git add test1.txt
git commit -m "test1" -a

git checkout -b patches master

echo "test2" > test2.txt
git add test2.txt
git commit -m "test2" -a

git checkout master

echo "test3" > test3.txt
git add test3.txt
git commit -m "test3" -a

echo "test4" > test4.txt
git add test4.txt
git commit -m "test4" -a

echo "test5" > test5.txt
git add test5.txt
git commit -m "test5" -a

git checkout patches
git merge master    

#Now how to get a branch having all commits from patches + test3.txt + test4.txt - test5.txt ???

基本的に私が欲しいのは、ファイル1〜4でブランチの「パッチ」をチェックアウトすることだけですが、test5.txtは含まれていません。

行うこと: git checkout [sha_where_test4.txt_entered]

... test1、test3、test4でブランチを提供しますが、test2.txtは除外します

より複雑な例:

#!/bin/bash

rm -rf ./.git
git init

echo "test1" > test1.txt
git add test1.txt
git commit -m "test1" -a

git checkout -b patches master

echo "test2" > test2.txt
git add test2.txt
git commit -m "test2" -a

git checkout master

echo "test3" > test3.txt
git add test3.txt
git commit -m "test3" -a

echo "test4" > test4.txt
git add test4.txt
git commit -m "test4" -a

echo "test5" > test5.txt
git add test5.txt
git commit -m "test5" -a

git checkout patches
git merge master

echo "test6" > test6.txt
git add test6.txt
git commit -m "test6" -a

#Now how to get a branch having all commits from patches + test3.txt + test4.txt - test5.txt ???
git log --topo-order | cat

# Now I need something to help me going back to history 
# without manually calculating that patches~2 sha's
git checkout -b patches.tmp master~1
git merge patches~2

ありがとう。

4

3 に答える 3

1

最初の例に関しては、test2の上にtest3と4を再生する必要があります。これは次の典型的なケースですrebase --onto

から始まる:

代替テキストhttp://img169.imageshack.us/img169/2255/gitr1.png

現在のパッチの配置をマークし、終了するパッチブランチを移動します(test4):

C:\Prog\Git\tests\rep\main>git checkout patches
Switched to branch 'patches'

C:\Prog\Git\tests\rep\main>git checkout -b tmp
Switched to a new branch 'tmp'

C:\Prog\Git\tests\rep\main>git checkout patches
Switched to branch 'patches'

C:\Prog\Git\tests\rep\main>git reset --hard master~1
HEAD is now at 8448d0f test4

それはあなたに与えます:

代替テキストhttp://img169.imageshack.us/img169/4826/gitr2.png

そして、コミットの正しいシーケンスが必要なものにリベースするだけです。

C:\Prog\Git\tests\rep\main>git checkout tmp
Switched to branch 'tmp'

C:\Prog\Git\tests\rep\main>git rebase --onto tmp tmp~1 patches
First, rewinding head to replay your work on top of it...
Applying: test3
Applying: test4

これは次のようになります。

代替テキストhttp://img52.imageshack.us/img52/372/gitr3.png

これは、線形のコミットセットを移動する場合にのみ機能します。

于 2010-03-14T19:59:42.163 に答える
1

そのような点はありません。ここには2つの並列開発パスがあります。1つはファイルtest1とtest2を含み、もう1つはファイルtest1、test3、test4、test5を含みます。ただし、マージを使用してそのようなポイントを作成できます。

test4を追加するコミットのSHA1を確認し、test2を追加するコミットとマージします。たとえば、スクリプトを実行した後、私のリポジトリは次のようになります。

*   b054987 (HEAD, patches) Merge branch 'master' into patches
|\  
* | 5ae790f test2
| * f2a3dac (master) test5
| * 70e8cd2 test4
| * c4102ed test3
|/  
* d448eaa test1

これで、実行します:

% git checkout 70e8c
% git merge 5ae79

結果は、ファイル1〜4を含むHEADです。

*   bcc8f7a (HEAD) Merge commit '5ae79' into HEAD
|\  
| | *   b054987 (patches) Merge branch 'master' into patches
| | |\  
| |/ /  
| * | 5ae790f test2
| | * f2a3dac (master) test5
| |/  
|/|   
* | 70e8cd2 test4
* | c4102ed test3
|/  
* d448eaa test1

% ls
test1.txt   test2.txt   test3.txt   test4.txt

これで、好きな場所からブランチを作成できます。

于 2010-03-14T18:58:58.420 に答える
0

操作は戻って履歴を変更するgit mergeのではなく、元の2つの履歴を指す新しいコミットを作成します。だから、写真では、あなたが持っているものは次のようなものです:

  2----------- \
 / \
1 --- 3 --- 4 --- 5 --- M(HEAD)

履歴を巻き戻してリビジョン4に戻すと、ファイル1、3、および4が取得されますが、 2は取得されません

于 2010-03-14T18:56:03.210 に答える