1

スカッシュの同様の結果を得るために、このワークフローに何か問題がありますか?

  • master という名前の新しいブランチをチェックアウトしますdraft_feature_a
  • たくさんのコミットを行います。一部のコミットはコードを壊します。ずさんなコミット メッセージを持つものもあります。
  • マスターをチェックアウトし、マスターのチェックアウトから、という名前の新しいブランチfeature_a
  • 次のようにして、ドラフト機能から最終的な変更を取り込みますgit checkout draft_feature_a $(git diff --name-only master draft_feature_a)

これで最終的な変更が完了し、pretty commit メッセージでそれらをコミットできます。

4

3 に答える 3

2

たとえば、ファイルの削除はキャプチャされません。

$ git checkout draft_feature_a $(git diff --name-only master draft_feature_a)
error: pathspec 'ttt.py' did not match any file(s) known to git.

実際の rebase-and-squash-etc で同じことを行うことができます (以下で "fixup" を使用しましたが、ほとんど同じことです。元のコミットはすべて で引き続き表示できますdraft_feature_a)。

$ git checkout -b draft_feature_a
[work, commit, etc - I made two commits: add newfile and rm ttt.py]
$ git checkout master
Switched to branch 'master'
$ git checkout -b feature_a
Switched to a new branch 'feature_a'
$ git merge draft_feature_a
Updating 523bacb..3a486fc
Fast-forward
 newfile |  0
 ttt.py  | 14 --------------
 2 files changed, 14 deletions(-)
 create mode 100644 newfile
 delete mode 100644 ttt.py
git rebase -i master
[edit to make everything but the first a "fixup"]
...
 2 files changed, 14 deletions(-)
 create mode 100644 newfile
 delete mode 100644 ttt.py
Successfully rebased and updated refs/heads/feature_a.
$ git commit --amend
[edit commit message]

私は実際にこのようなワークフローをよく使用しますが、ほとんどの場合、ドラフト作業を「git rebase -i」するだけです。別の「ドラフト」ブランチを作成するかどうかに関係なく、元のコミットが利用可能であることに注意してください。それらは名前を失うだけであり、コミット ID を見つけるために reflog を掘り下げる必要があります。新しいブランチを作成して「git merge」する代わりに、新しい名前を追加できます。

(まず、前の例をクリーンアップしましょう)

$ git checkout master
Switched to branch 'master'
$ git branch -D draft_feature_a
Deleted branch draft_feature_a (was 3a486fc).
$ git branch -D feature_a
Deleted branch feature_a (was 0fc36f0).

(今は新しい例です)

$ git checkout -b feature_a
Switched to a new branch 'feature_a'
[work work work]
[time to clean up, let's stick a label on this version so I can find it easily:]
$ git branch messy_feature_a feature_a
$ git rebase -i master

リベースが完了し、すべてが押しつぶされ、修正され、再配置され、コミットメッセージが編集されたなど、何かを台無しにしたと判断した場合でも、すべての「ドラフト」(低品質/乱雑)の作業は引き続き利用できます「乱雑な」名前で名前で。満足して古い名前が不要になったら、手動で削除します ( git branch -D)。

これを理解するための秘訣は、git で何かを行うたびに、新しいコミットのみを追加するということです。古いものは、(最終的に) それらを「ガベージ コレクション」するために暗黙的または明示的な何かを行うまで、リポジトリに残ります。3a486fcスタイル SHA1 名以外でコミットを名前付けできるようにするブランチ ラベル名 (またはタグなどの他の「目に見える」名前) がある限り、それらは「永久に」存続します。ブランチを削除すると、単にラベルが消去されます。1 ~ 3 か月後、ラベルのないコミットは最終的にガベージ コレクションされます。(より正確には、有効期限が切れるまで reflog に名前が残っています。reflog エントリには時間制限があります。 のドキュメントgit reflog、特に--expire=<time>パラメータを参照してください。)

同様に、「リベース」は新しい一連のコミットを作成し、そこにすべての古いコミットを残します。リベースが完了すると、git は古い一連のコミットの末尾からラベルを剥がし、それを新しい一連のコミットの末尾に貼り付けます。

A -- B -- C          [label: master]
           \
            D -- E   [label: feature_a]

[rebase feature_a on master, and squash or fixup to make commit DE which is D+E]

A -- B -- C          [label: master]
          | \
          |  D -- E  [no label!]
          \
            DE       [label: feature_a]

リベースを行う前に余分なラベルを追加すると、現在のブランチのfeature_aラベル​​は剥がされて新しいコミットに移動されますが、他のラベル ( messy_feature_a) は残り、コミット E に簡単にアクセスできます。チェーン (C から分岐する D と E)。

于 2013-06-06T01:33:42.947 に答える