291

特定のブランチの一部のみであるすべてのコミットを一覧表示したいと考えています。

以下では、ブランチからのすべてのコミットだけでなく、親 (マスター) からのすべてのコミットも一覧表示します。

git log mybranch

私が見つけた他のオプションは、マスターが到達可能なコミットを除外して、私が望むものを提供することでしたが、他のブランチ名を知る必要を避けたいと思います。

git log mybranch --not master

を使用しようとしてgit for-each-refいましたが、mybranch もリストされているため、実際にはすべて除外されています。

git log mybranch --not $(git for-each-ref --format '^%(refname:short)' refs/heads/)

アップデート:

少し前に見つけた新しいオプションをテストしていますが、今のところ、これが私が探していたものである可能性があります。

git log --walk-reflogs mybranch

更新 (2013-02-13T15:08):

--walk-reflogs オプションは良いですが、reflog の有効期限 (デフォルトは 90 日、gc.reflogExpire ) があることを確認しました。

私が探していた答えを見つけたと思います:

git log mybranch --not $(git for-each-ref --format='%(refname)' refs/heads/ | grep -v "refs/heads/mybranch")

利用可能なブランチのリストから現在のブランチを削除し、そのリストを使用してログから除外しています。このようにして、 mybranch によってのみ到達されるコミットのみを取得します。

4

16 に答える 16

235

使用する必要があるように聞こえるものからcherry

git cherry -v develop mybranch

これにより、 mybranchに含まれているが、 developには含まれていないすべてのコミットが表示されます。最後のオプション ( mybranch ) を省略すると、代わりに現在のブランチが比較されます。

VonC が指摘したように、常に自分のブランチと別のブランチを比較しているので、自分のブランチを知ってから、比較するブランチを選択してください。

于 2014-07-10T04:18:00.470 に答える
37

OPが望んでいたことを行う方法をついに見つけました。次のように簡単です。

git log --graph [branchname]

このコマンドは、提供されたブランチから到達可能なすべてのコミットをグラフの形式で表示します。*ただし、コミット行の最初の文字であるコミット グラフを見ることで、そのブランチのすべてのコミットを簡単にフィルター処理できます。

たとえば、git log --graph master以下の on cakephp GitHub リポジトリの抜粋を見てみましょう。

D:\Web Folder\cakephp>git log --graph master
*   commit 8314c2ff833280bbc7102cb6d4fcf62240cd3ac4
|\  Merge: c3f45e8 0459a35
| | Author: José Lorenzo Rodríguez <lorenzo@users.noreply.github.com>
| | Date:   Tue Aug 30 08:01:59 2016 +0200
| |
| |     Merge pull request #9367 from cakephp/fewer-allocations
| |
| |     Do fewer allocations for simple default values.
| |
| * commit 0459a35689fec80bd8dca41e31d244a126d9e15e
| | Author: Mark Story <mark@mark-story.com>
| | Date:   Mon Aug 29 22:21:16 2016 -0400
| |
| |     The action should only be defaulted when there are no patterns
| |
| |     Only default the action name when there is no default & no pattern
| |     defined.
| |
| * commit 80c123b9dbd1c1b3301ec1270adc6c07824aeb5c
| | Author: Mark Story <mark@mark-story.com>
| | Date:   Sun Aug 28 22:35:20 2016 -0400
| |
| |     Do fewer allocations for simple default values.
| |
| |     Don't allocate arrays when we are only assigning a single array key
| |     value.
| |
* |   commit c3f45e811e4b49fe27624b57c3eb8f4721a4323b
|\ \  Merge: 10e5734 43178fd
| |/  Author: Mark Story <mark@mark-story.com>
|/|   Date:   Mon Aug 29 22:15:30 2016 -0400
| |
| |       Merge pull request #9322 from cakephp/add-email-assertions
| |
| |       Add email assertions trait
| |
| * commit 43178fd55d7ef9a42706279fa275bb783063cf34
| | Author: Jad Bitar <jadbitar@mac.com>
| | Date:   Mon Aug 29 17:43:29 2016 -0400
| |
| |     Fix `@since` in new files docblocks
| |

ご覧のとおり、コミットのみがコミット行の最初の文字になってい8314c2ff833280bbc7102cb6d4fcf62240cd3ac4ますc3f45e811e4b49fe27624b57c3eb8f4721a4323b*これらのコミットは master ブランチからのもので、他の 4 つのコミットは他のブランチからのものです。

于 2016-08-31T03:09:09.207 に答える
14

次のシェルコマンドは、あなたが望むことをするはずです:

git log --all --not $(git rev-list --no-walk --exclude=refs/heads/mybranch --all)

注意事項

チェックアウトした場合mybranch、上記のコマンドは機能しません。これは、 のコミットmybranchが からも到達可能HEADであるためです。そのため、Git はコミットが に固有のものであるとは見なしませんmybranch。がチェックアウトされたときに機能させるにmybranchは、除外対象も追加する必要がありますHEAD

git log --all --not $(git rev-list --no-walk \
    --exclude=refs/heads/mybranch \
    --exclude=HEAD \
    --all)

ただし、がチェックアウトされていない限り、除外しないでください。そうしないと、 に排他的ではないコミットが表示される危険があります。HEADmybranchmybranch

同様にorigin/mybranch、ローカル ブランチに対応する名前のリモート ブランチがある場合はmybranch、それを除外する必要があります。

git log --all --not $(git rev-list --no-walk \
    --exclude=refs/heads/mybranch \
    --exclude=refs/remotes/origin/mybranch \
    --all)

また、リモート ブランチがリモート リポジトリのデフォルト ブランチである場合 (通常は のみに該当します)、同様origin/masterに除外する必要があります。origin/HEAD

git log --all --not $(git rev-list --no-walk \
    --exclude=refs/heads/mybranch \
    --exclude=refs/remotes/origin/mybranch \
    --exclude=refs/remotes/origin/HEAD \
    --all)

ブランチをチェックアウトし、リモート ブランチがありリモートブランチがリモート リポジトリのデフォルトである場合、多くを除外することになります。

git log --all --not $(git rev-list --no-walk \
    --exclude=refs/heads/mybranch \
    --exclude=HEAD
    --exclude=refs/remotes/origin/mybranch \
    --exclude=refs/remotes/origin/HEAD \
    --all)

説明

このgit rev-listコマンドは、指定されたリビジョンを調べて、検出された SHA1 識別子をダンプする低レベル (配管) コマンドです。git logSHA1 のみが表示されることを除けば、ログ メッセージ、作成者名、タイムスタンプなどの「凝った」ものは表示されないという点を除けば、同等と考えてください。

このオプションは、名前が示すように、祖先の連鎖をたどる--no-walkことを防ぎます。git rev-listしたがって、入力git rev-list --no-walk mybranchすると、1 つの SHA1 識別子のみが出力されます:mybranchブランチの先端コミットの識別子です。

--exclude=refs/heads/mybranch --all引数は、 を除く各参照から開始するように指示しgit rev-listますrefs/heads/mybranch

そのため、 を実行するgit rev-list --no-walk --exclude=refs/heads/mybranch --allと、Git は を除く各参照のチップ コミットの SHA1 識別子を出力しrefs/heads/mybranchます。これらのコミットとその祖先は、関心のないコミットです。これらは、表示したくないコミットです。

他のコミットはあなたが見たいものなので、出力を収集し、git rev-list --no-walk --exclude=refs/heads/mybranch --allそれらのコミットとその祖先以外のすべてを表示するように Git に指示します。

この--no-walk引数は、大規模なリポジトリには必要です (これは小規模なリポジトリの最適化です): これがないと、Git は出力する必要があり、シェルは必要以上に多くのコミット ID を収集 (およびメモリに格納) する必要があります。大規模なリポジトリでは、収集されたコミットの数がシェルのコマンドライン引数の制限を簡単に超える可能性があります。

バグ?

私は次のように動作することを期待していました:

git log --all --not --exclude=refs/heads/mybranch --all

しかし、そうではありません。これは Git のバグだと思いますが、意図的なものかもしれません。

于 2014-09-12T05:14:33.720 に答える
11

素早い答え:

git log $(git merge-base master b2)..HEAD

まあ言ってみれば:

  1. masterブランチがあること

  2. いくつかのコミットを行う

  3. b2という名前のブランチを作成しました

  4. するgit log -n1; コミット ID は、b2 とマスターの間のマージ ベースです。

  5. b2でいくつかのコミットを行います

  6. git logb2 と master のログ履歴が表示されます

  7. コミット範囲を使用してください。概念に慣れていない場合は、Google で検索するか、overflow-it をスタックすることをお勧めします。

    実際のコンテキストについては、たとえば次のことができます

    git log commitID_FOO..comitID_BAR
    

    「..」は、log コマンドの範囲演算子です。

    つまり、単純な形式で、commitID_FOO よりも新しいすべてのログを教えてください...

  8. ポイント#4、マージベースを見てください

    だから:git log COMMITID_mergeBASE..HEADあなたの違いを示します

  9. Git は、このようにマージ ベースを取得できます

    git merge-base b2 master
    
  10. 最後に、次のことができます。

    git log $(git merge-base master b2)..HEAD
    
于 2014-01-18T14:50:18.573 に答える
4

次のようなことを試すことができます:

#!/bin/bash

all_but()
{
    target="$(git rev-parse $1)"
    echo "$target --not"
    git for-each-ref --shell --format="ref=%(refname)" refs/heads | \
    while read entry
    do
        eval "$entry"

        test "$ref" != "$target" && echo "$ref"
    done
}

git log $(all_but $1)

または、 Git User's Manual のレシピから借ります:

#!/bin/bash
git log $1 --not $( git show-ref --heads | cut -d' ' -f2 | grep -v "^$1" )
于 2013-02-13T07:48:56.967 に答える