Git을 사용하여 하나의 특정 브랜치에 * 오직 * 존재하는 모든 커밋을 표시하고 * 아무 ** 다른 브랜치에는 표시하지 않습니다. 한 지점에

분기가 주어지면 해당 분기 에만 존재하는 커밋 목록을보고 싶습니다 . 에서 이 질문에 우리는 한 지점에 있지만 그 이상의 다른 지점을 지정하지 않은 한 어떤 커밋을 참조하는 방법에 대해 설명합니다.

이것은 약간 다릅니다. 나는 1 분기에 있지만에있는 커밋보고 싶은 어떤 다른 지점.

유스 케이스는 일부 분기가 병합되어야하고 직접 커밋되지 않아야하는 분기 전략에 있습니다. 이것은 “병합 전용”브랜치에서 직접 커밋이 이루어 졌는지 확인하는 데 사용됩니다.

편집 : 아래는 테스트 할 더미 git repo를 설정하는 단계입니다.

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt
git commit -am "2nd valid commit on master"
git checkout merge-only
git merge master

병합 전용 브랜치에서 직접 작성된 “병합 전용에서 직접 잘못된 커밋”메시지가있는 커밋 만 표시되어야합니다.



답변

우아한 솔루션을 찾았습니다.

git log --first-parent --no-merges

물론 귀하의 예에서는 초기 커밋이 여전히 표시됩니다.

이 답변은 초기 커밋이 여전히 나타나기 때문에 질문에 정확히 대답하지 않습니다. 다른 한편으로 여기에 오는 많은 사람들은 그들이 찾고있는 답을 찾는 것 같습니다.


답변

내 친애하는 친구 Redmumba의 의례 :

git log --no-merges origin/merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/remotes/origin |
    grep -Fv refs/remotes/origin/merge-only)

origin/merge-only원격 병합 전용 분기 이름은 어디에 있습니까 ? 로컬 전용 자식의 repo, 대체 작업을하는 경우 refs/remotes/originrefs/heads, 그리고 대체 원격 지사 이름 origin/merge-only지역 지점 이름 merge-only, 즉 :

git log --no-merges merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/heads |
    grep -Fv refs/heads/merge-only)

답변

git log origin/dev..HEAD

그러면 브랜치에서 이루어진 모든 커밋이 표시됩니다.


답변

@Prakash 답변이 작동합니다. 명확성을 위해 …

git checkout feature-branch
git log master..HEAD

기능 분기에 대한 커밋을 나열하지만 업스트림 분기 (일반적으로 마스터)는 나열하지 않습니다.


답변

아마도 이것이 도움이 될 수 있습니다.

git show-branch

답변

이 시도:

git rev-list --all --not $(git rev-list --all ^branch)

기본적으로 git rev-list --all ^branch분기에없는 모든 개정을 가져온 다음 저장소의 모든 개정을 가져오고 분기 에만 있는 개정 인 이전 목록을 뺍니다 .

@Brian의 댓글 이후 :

git rev-list의 문서에서 :

List commits that are reachable by following the parent links from the given commit(s)

따라서 git rev-list AA가 커밋 인 경우 와 같은 명령 은 A를 포함하여 A에서 도달 할 수있는 커밋을 나열합니다.

이를 염두에두고

git rev-list --all ^A

A에서 도달 할 수없는 커밋을 나열합니다.

따라서 git rev-list --all ^branch분기 끝에서 도달 할 수없는 모든 커밋을 나열합니다. 이것은 분기의 모든 커밋을 제거하거나 다른 분기에만있는 커밋을 제거합니다.

이제 가자 git rev-list --all --not $(git rev-list --all ^branch)

이것은 git rev-list --all --not {commits only in other branches}

그래서 우리 all는 도달 할 수없는 목록 을 원합니다.all commits only in other branches

분기 에만있는 커밋 집합입니다 . 간단한 예를 들어 보겠습니다.

             master

             |

A------------B

  \

   \

    C--------D--------E

                      |

                      branch

여기서 목표는 다른 브랜치에없는 커밋 인 D와 E를 얻는 것입니다.

git rev-list --all ^branch B 만 주다

자, git rev-list --all --not B우리가 내려 오는 것입니다. 또한 git rev-list -all ^BB에서 도달 할 수없는 모든 커밋을 원합니다. 우리의 경우 D와 E입니다. 이것이 우리가 원하는 것입니다.

이것이 명령이 올바르게 작동하는 방법을 설명하기를 바랍니다.

댓글 후 수정 :

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt
git commit -am "2nd valid commit on master"

위의 단계 후에, 당신이한다면 당신은 git rev-list --all --not $(git rev-list --all ^merge-only)당신이 찾고 있던 커밋을 얻을 "bad commit directly on merge-only"것입니다.

그러나 단계의 마지막 단계를 수행 git merge master하면 명령이 예상 된 출력을 제공하지 않습니다. 현재 마스터의 추가 커밋도 병합 전용으로 병합되었으므로 병합 전용에없는 커밋이 없기 때문입니다. 그래서 git rev-list --all ^branch빈 결과를 제공하고, 따라서 git rev-list -all --not $(git rev-list --all ^branch)줄 것이다 모든 병합 만에 커밋.


답변

허용되는 답변의 또 다른 변형은 master

git log origin/master --not $(git branch -a | grep -Fv master)

마스터 이외의 분기에서 발생하는 모든 커밋을 필터링합니다.