Git을 사용하여 두 날짜 사이에 발생한 모든 커밋 간의 차이를 어떻게 얻을 수 있습니까?


116

아니면 두 날짜 사이에 발생한 모든 커밋? SVN에서는 다음과 같이 할 수 있습니다.

svn diff -r{date}:{date}

그것을하기 위하여! 이에 상응하는 Git을 찾을 수없는 것 같습니다.

특히 나는 그날 누구에 의해 커밋 된 모든 코드와 함께 매일 이메일을 보내는 스크립트를 작성하려고합니다.

답변:


159

당신은 사용할 수 있습니다 git whatchanged --since="1 day ago" -p

또한 --until논쟁 이 필요합니다 .

문서


감사! 이것은 내가 원한 것이 옳았으며 문서에 나열되지는 않았지만 --committer 매개 변수도 사용합니다! 또한 'git whatchanged'가 'git help'에 나타나지 않았습니다! 이유는 모르겠지만 ... 다시 한 번 감사합니다.
Chris

5
세스가 카르마를 얻을 수 있도록이 답을 선택해야합니다.
Scott

18
@brbob 나는 이것이 오래 전에 대답했다는 것을 알고 있지만 (내가 한 것처럼) 이것을 우연히 발견 한 사람을 위해 Git help는 말한다 : The command is kept primarily for historical reasons; fingers of many people who learned Git long before git log was invented by reading Linux kernel mailing list are trained to type it. 그래서, 문서는 git log대신 사용하도록 권장합니다 git whatchanged. 이 마지막 명령은 git log의 --no-merge 옵션도 사용하므로 동일한 결과를 출력합니다.
Ramses

2
git whatchanged는 git log의 문서
Vincent

2
git whatchanged현재 최신 버전 2.21.0에서 더 이상 사용되지 않습니다. git whatchanged달성 된 모든 것은에 의해 달성 될 수 있으며 git log역사적 이유로 만 보존됩니다. 자세한 내용보기 git-scm.com/docs/git-whatchanged/2.21.0
Devy

60

이전 제안에는 몇 가지 단점이 있습니다. 기본적으로 나는 cvs diff -D"1 day ago" -D"2010-02-29 11:11". 점점 더 많은 정보를 수집하면서 해결책을 찾았습니다.

내가 시도한 것 :

  • git whatchanged --since="1 day ago" -p에서 여기

    그러나 이것은 하나의 파일에 여러 커밋이 있더라도 각 커밋에 대한 차이를 제공합니다. 나는 "date"가 git에서 약간 느슨한 개념이라는 것을 알고있다 . 나는 이것을 할 수있는 방법이 있어야한다고 생각했다.

  • git diff 'master@{1 day ago}..master약간의 경고를 제공하고 warning: Log for 'master' only goes back to Tue, 16 Mar 2010 14:17:32 +0100.모든 diff를 표시하지 않습니다.

  • git format-patch --since=yesterday --stdout 나를 위해 아무것도주지 않습니다.

  • revs=$(git log --pretty="format:%H" --since="1 day ago");git diff $(echo "$revs"|tail -n1) $(echo "$revs"|head -n1) 어떻게 든 작동하지만 복잡해 보이며 현재 분기로 제한되지 않습니다.

드디어:

  • git diff $(git rev-list -n1 --before="1 day ago" master)내가 생각했던 것보다 더 복잡하지만 작동하고 비슷한 일을 하는 기본 방법 인 것 같습니다 .

재미있게도 git-cvsserver는 "cvs diff -D"를 지원하지 않습니다 (어딘가에 문서화되어 있지 않은 경우).


4
+1은 git rev-list내가 본 것과 매우 유사한 문제를 해결하는 데 큰 도움이되었습니다.
me_and

이것은 받아 들여지는 대답이 아니어야하며 seth 's는 더 간결하고 정확합니다.
ctford 2014 년

6
@ctford, 내 견해로는 올바르지 않습니다. svn / cvs diff로 파일 당 하나의 diff가 아니라 하나의 파일에 대해 여러 diff를보고 할 수 있습니다.
Weidenrinde

1
1 @Weidenrinde이 훨씬 더 똑똑
rostamn739

1
git diff 'master@{1 day ago}..master구문 수단은 "확인 reflog 분기 곳을 그림 master지점으로 사용 하여 로컬 저장소에를 1 day ago ". 특히 현재 분기의 실제 커밋 내역을 사용하지 않습니다 master. 이것은 당신이 정말로 원하는 것은 거의 없습니다.
Mikko Rantalainen

22

"날짜"는 git에서 약간 느슨한 개념입니다. 커밋에는 누군가가 실제로 커밋을 리포지토리로 가져 오기 / 커밋하기 전에 어느 정도 시간이 지난 작성 날짜가있을 수 있으며, 또한 커밋이 새로 워진 커밋 위에 업데이트되고 업데이트 될 수 있습니다.

커밋에는 커밋이 갱신되거나 어떤 식 으로든 수정되면 업데이트되는 커밋 날짜도 있습니다. 이러한 커밋은 일종의 연대순 일 가능성이 더 높지만 여전히 커미터가 자신의 컴퓨터에 정확한 시간을 설정하고 있기 때문에 수정되지 않은 커밋은 이전에 원격 저장소의 기능 브랜치에 무기한 위치 할 수 있습니다. 중앙 저장소의 마스터 브랜치로 병합됩니다.

귀하의 목적에 가장 유용한 것은 문제가되는 특정 저장소의 리플 로그 날짜입니다. 분기 별 reflog가 활성화 된 경우 (참조 git config core.logAllRefUpdates) ref@{date}구문을 사용하여 특정 시간에 분기가 있었던 위치를 참조 할 수 있습니다 .

git log -p master@{2009-07-01}..master@{now}

다음과 같은 '모호한'설명을 사용할 수도 있습니다.

git log -p "master@{1 month ago}..master@{yesterday}"

이 명령은 작성자 및 커밋 날짜에 따라 실제로 '오래된'상태인지에 관계없이 저장소의 지정된 분기에 '나타난'모든 커밋을 표시합니다.

분기 별 reflog는 리포지토리에 따라 다르므로 복제본에서 log 명령을 실행하고 한 달 동안 가져 오지 않은 경우 지난 달의 모든 변경 사항을 한 번에 가져옵니다. 그러면 지난달의 모든 변경 사항이 @{1 hour ago}..@{now}범위에 표시됩니다 . 사람들이 푸시하는 '중앙'저장소에서 log 명령을 실행할 수 있다면 원하는 작업을 수행 할 수 있습니다.


서술 된 질문에 대한 아주 좋은 글과 좋은 대답 ...하지만 brbob이 의도 한 것을하는 데는별로 도움이되지 않을 것 같습니다.
Jakub Narębski

특정 중앙 저장소의 특정 분기로 푸시 된 항목을 실제로 구문 분석하고 해당 저장소에서 log 명령을 실행하면 도움이 될 수 있습니다. 편집이 필요하다고 생각합니다 ...
CB Bailey

"커밋이 갱신되거나 어떤 식 으로든 수정되면 업데이트되는 커밋 날짜", 실제로 날짜는 변경되지 않습니다. 전체 커밋이 다른 커밋으로 대체됩니다 (트리가 동일 할 수도 있음).
hasen

2
@hasen j : 기술적으로 맞습니다. 커밋은 변경할 수 없습니다. 커밋을 리베이스하거나 수정하고 새 커밋을 만들 때 기존 커밋 메시지, 작성자 세부 정보 및 작성자 날짜가 종종 이전 커밋에서 복사되므로 새 커밋 ID와 커밋 날짜로 커밋을 업데이트하는 것과 같습니다 .
CB Bailey

점을 유의 @{time spec}구문은 항상 의미 귀하의 지역 reflog를 . 실제 커밋 기록 (DAG)을 참조하지 않습니다. 차이점을 이해하지 못한다면이 구문을 사용하지 마십시오!
Mikko Rantalainen

14
git diff --stat @{2013-11-01}..@{2013-11-30}

또는

git diff --stat @{2.weeks.ago}..@{last.week}

이것은 리플 로그에 의존합니까? 그럴 경우이 명령을 실행하는 저장소가 포함 된 커밋 기록보다 최신 (즉, 새로 복제 된) 경우 실제로 사용할 수 없습니다.

2
예, 이것은 전적으로 reflog에 달려 있습니다. 그리고 예, 이것은 로컬 복사 기록에서만 작동하지만 약간 편리한 명령입니다.
AA.

1
예, 당신이 그것을 지원할만큼 충분히 오래된 reflog 항목이있는 한 그것이 편리하다는 데 확실히 동의합니다.

AA 감사합니다. 귀하의 답변을 사용하여 다음과 같이 할 수있었습니다. git annotate --stat .. @ {2017-08-8} filename | less; git annotate --stat .. @ {5.days.ago} 파일 이름; 상황의 변화를 볼 수 있습니다.
크리스

점을 유의 @{time spec}구문은 항상 의미 귀하의 지역 reflog를 . 실제 커밋 기록 (DAG)을 참조하지 않습니다. 차이점을 이해하지 못한다면이 구문을 사용하지 마십시오!
Mikko Rantalainen

4

혹시

$ git format-patch --committer=<who> --since=yesterday --stdout

원하는 것 ( '--stdout'포함 또는 제외)입니까?


1
빠른 질문,-이후 커밋 날짜를 사용합니까?
CB Bailey

3

일반적인 해결책은 다음을 사용하는 것입니다.

git rev-list -n1 --first-parent --until=<a date string> <a ref>

--first-parent가 없으면 나중에 병합 된 브랜치에서 커밋을 얻을 수 있습니다. a ref 되었지만에서 병합되지 않은a date string .

다음은 --childrengrep대신 사용하는 대안 입니다 -n1.

mlm_git_ref_as_of() {
    # # Examples #
    #
    # Show all commits between two dates:
    #
    #     git log $(mlm_git_ref_as_of '2012-05-21 09:00:00-0400')..$(mlm_git_ref_as_of '2012-05-21 17:00:00-0400')
    #
    # Show diffs of all commits between two dates:
    #
    #     git diff $(mlm_git_ref_as_of '2012-05-21 09:00:00-0400')..$(mlm_git_ref_as_of '2012-05-21 17:00:00-0400')
    local as_of="$1"
    local ref="${2:-HEAD}"
    # Get the most recent commit (--children, grep -v ' ') that was on
    # the given branch ($ref, --first-parent) as of a given date
    # ($as_of)
    git rev-list --children --first-parent --until="$as_of" "$ref" | grep -v ' '
}

git whatchanged이 Q & A를 읽기 전에는 잘 알지 못했지만 결과가 매우 달라서 어떤 일을하는지 잘 모르겠습니다.


3

특정 날짜 이후의 모든 변경 사항을 비교할 수있는 또 다른 간단한 방법은 X해당 날짜 또는 그 이후에 발생한 첫 번째 커밋 을 찾은 다음 사용하는 것입니다.

git diff X

이것은 새로운 클론의 리플 로그 항목에 의존하지 않는다는 장점이 있습니다.

git diff <reference>@{n}..
git log <reference>@{n}..

솔루션


2

더 나은 방법이 있기 때문에 이것은 더 재미있는 대답입니다. 오늘의 모든 커밋 해시가 표시됩니다.

git log --pretty="format:%H %ai" | grep `date +"%Y-%m-%d"` | awk {'print $1'}`

; ·)


2

git-format-patch를 사용할 수도 있습니다. 패치 (차이점)을 준비하고 이메일을 통해 보낼 수 있습니다.

커밋 범위를 지정하려면 [since] 또는 [revision range] 옵션을 사용하십시오.


2

분기 에서 Git 파일이 날짜별로 변경되는 것을 보려면 다음 공식을 사용하십시오.

  1. 지점을 확인하십시오.
  2. 원격 저장소에서 변경 사항 가져 오기 및 업데이트
  3. 날짜에서 날짜 범위까지 다른 파일보기

공식 :

git checkout <branch>
git pull
git diff --stat @{fromDate}..@a{toDate}

날짜가 YYYY-MM-DD 형식 임을주의하십시오 .

git diff --stat @{2019-08-20}..@a{2019-08-21}

특정 시간 범위에서 특정 파일의 변경 사항 을 관찰하려면 (코드에서 diff 확인) 현재 파일을 탐색하면됩니다.

:

git diff @{2019-01-01}..@{2019-01-02} ~/dev/myApp/package.json

0

나는 내가하는 방식으로 던질 것이다. git log날짜는 현재 브랜치에 대한 커밋 해시를 제공한다. 그런 다음 git diff 8fgdfg8..565k4l5파일별로 집계 된 적절한 차이를 제공 하는 것과 같은 것을 사용 합니다. 이것이 도움이되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.