날짜별로 Git에서 결제하는 방법은 무엇입니까?


314

소스 코드에서 회귀를 작업 중입니다. Git에 "매개 변수 날짜 / 시간을 기준으로 소스를 체크 아웃하십시오"라고 말하고 싶습니다. 이게 가능해?

또한 현재보기에서 잃고 싶지 않은 변경 사항을 단계별로 적용했습니다. 이상적으로는 현재 소스와 이전 날짜를 기준으로 관심있는 일부 버전 사이를 전환하고 싶습니다.


9
다만 경우에 당신이 그것에 대해 모르는 자식 양분은 회귀 분석을 찾기위한 매우 중대하다. 앤디가 말한 {1 년 전} 구문을 사용하여 잘 알려진 커밋을 찾은 다음이를 초기 git bisect good지점 으로 사용합니다 .
MatrixFrog

이것이 좋은 사용 사례 인 것 같습니다 tags.
Jess

답변:


365

현재 변경 사항을 유지하려면

로 커밋하지 않고 작업을 숨길 수 있습니다 git stash. 당신은 git stash pop그것을 다시 얻기 위해 사용 하는 것보다 . 또는 ( 칼리토가 말했듯이) git commit별도의 지점 으로 수 있습니다 .

rev-parse를 사용하여 날짜 별 체크 아웃

다음을 사용하여 특정 날짜까지 커밋을 체크 아웃 할 수 있습니다 rev-parse.

git checkout 'master@{1979-02-26 18:30:00}'

사용 가능한 옵션에 대한 자세한 내용은에서 확인할 수 있습니다 git-rev-parse.

주석에서 언급 했듯이이 방법은 reflog를 사용하여 기록에서 커밋을 찾습니다. 기본적으로이 항목 은 90 일 후에 만료됩니다 . reflog 사용 구문이 덜 장황하지만 90 일만 되돌릴 수 있습니다.

rev-list를 사용하여 날짜별로 체크 아웃

reflog를 사용하지 않는 다른 옵션은 다음을 사용 rev-list하여 특정 시점에 커밋을 얻는 것입니다.

git checkout `git rev-list -n 1 --first-parent --before="2009-07-27 13:37" master`

병합으로 가져온 버전이 아닌 내역 만 원하는 경우 --first-parent를 참고하십시오 . 그것이 당신이 보통 원하는 것입니다.


2
@Rocky 더 자세한 정보를 제공해 주시겠습니까? 명령 행에 무엇을 입력하고 있으며 왜 작동하지 않는다고 말합니까? 오류 메시지가 나타 납니까?
Andy

8
@Rocky : 문제는 매개 변수를 따옴표로 묶어야한다는 것입니다. 그렇지 않으면 bash는 인수를 공백으로 구분합니다. 시도하십시오 git co 'master@{2 days ago}'.
Mark Wilden

13
참고 : 이동 거리에 따라 reflog (일부 시간이 지나면 만료 됨)를 사용하므로 작동하지 않을 수 있습니다. '경고 :'마스터 '에 대한 로그는 다음으로 돌아갑니다 ...'가 표시됩니다. Rocky의 솔루션은 항상 작동합니다. git checkoutgit rev-list -n 1 --before="2009-07-27 13:37" master
Mark Nadig

3
백틱이 더 이상 사용되지 않아 읽기 어렵 기 때문에 답변을 수정했습니다. 서브 쉘 $(...)이 선호됩니다.
Amedee Van Gasse

1
@ 앤디 행복한 40 번째 생일, 앤디! (의 어떤 1979년 2월 26일 : 의미한다고 가정)
데이비드 블레 빈스

123

앤디의 해결책이 나를 위해 작동하지 않습니다. 여기에 다른 방법이 있습니다.

git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`

힘내 : 날짜 별 체크 아웃


3
위의 명령을 실행하면 error: unknown switch `n'이 문제를 해결하는 방법에 대한 아이디어가 있습니까?
Tim

15

이 라인을 따라 무언가가 필요한 것 같습니다 : 날짜를 기준으로 Git 체크 아웃

즉, rev-list커밋을 찾은 다음 checkout을 사용하여 실제로 가져옵니다.

단계적 변경 사항을 잃지 않으려면 가장 쉬운 방법은 새 분기를 만들고 해당 분기에 커밋하는 것입니다. 분기간에 언제든지 전환 할 수 있습니다.

편집 : 링크가 다운되었으므로 다음 명령을 사용하십시오.

git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`

2
훌륭한 링크! 그래서 git checkout branch@{date}reflog가 만료되면 작동을 멈 춥니 다,하지만 당신은 사용할 수 있습니다 git checkout `git rev-list -n 1 --before="2009-07-27 13:37" master`.
cdunn2001

10

파이프 대체를 선호하는 사람들에게

git rev-list -n1 --before=2013-7-4 master | xargs git checkout

9

제 경우에는 -n 1옵션이 작동하지 않습니다. Windows에서 다음 명령 시퀀스가 ​​제대로 작동한다는 것을 알았습니다.

git rev-list -1 --before="2012-01-15 12:00" master

주어진 날짜에 대한 적절한 커밋의 SHA를 반환합니다.

git checkout SHA

4

git rev-parse당신이 관심있는 날짜가 인 경우 @Andy에 의해 제안 된 솔루션은 잘 작동 의 날짜를 커밋 . 당신이에 따라 체크 아웃 싶어하지만 경우 저자의 날짜 , rev-parse하지 작업이 옵션을 제공하지 않기 때문에 커밋을 선택하는 그 날짜를 사용하는 것입니다. 대신 다음을 사용할 수 있습니다.

git checkout $(
  git log --reverse --author-date-order --pretty=format:'%ai %H' master |
  awk '{hash = $4} $1 >= "2016-04-12" {print hash; exit 0 }
)

(또한 awk 술어 $1 >= "2016-04-12" && $2 >= "11:37"에서 시간 사용을 지정하려는 경우 )


3

rev-list마스터 브랜치에서 프로덕션 브랜치로 가장 최근의 병합 커밋을 찾으려면 이 옵션을 사용하십시오 (순전히 가상의 예).

git checkout `git rev-list -n 1 --merges --first-parent --before="2012-01-01" production`

주어진 날짜에 프로덕션 서버에 있던 코드를 찾아야했습니다. 이것은 나를 위해 그것을 발견했다.


2

빌드 할 때 리포지토리의 정확한 버전으로 돌아가려면 빌드 할 커밋에 태그를 지정하는 것이 가장 좋습니다.

다른 답변은 특정 시간 기준으로 지점에서 가장 최근의 커밋으로 리포지토리를 반환하는 기술을 제공하지만 항상 충분하지는 않습니다. 예를 들어, 분기에서 빌드 한 후 분기를 삭제하거나 나중에 다시 기반을 둔 분기에서 빌드하는 경우 빌드 한 커밋은 현재 분기의 git에서 "연결할 수 없음"이 될 수 있습니다. 리포지토리가 압축되면 git의 연결할 수없는 객체가 결국 제거 될 수 있습니다.

커밋에 태그를 추가하면 나중에 태그를 제거하지 않고 분기로 무엇을 하든지 태그에 도달 할 수 없게됩니다.


이것이 내가 찾는 답을 제공하지는 않지만, 지금까지 언급되지 않은 측면을 지적하는 것에 대한 언급이 필요합니다. 올바른 버전에 도달하지 못하게하는 문제의 원인 일 수 있습니다.
manuelvigarcia

1
git rev-list -n 1 --before="2009-07-27 13:37" origin/master

인쇄 된 문자열 (예 : XXXX)을 가져와 다음을 수행하십시오.

git checkout XXXX

2
이것은 @bartoszkp 답변과 중복되지 않습니까? 원산지에 대한 참조를 추가하는 것만으로도 다른 답변에 대한 코멘트가되어야합니다.
manuelvigarcia

그렇습니다. 사실 SHA가 무엇인지 모르는 사람을 위해 무엇을 복사 해야할지 거의 명확하게 정리합니다. 내 경우에는 텍스트가 명확하지 않고 솔루션을 찾은 후 내 코드입니다. 복사하지 않았습니다. 사실 볼 수 있습니다. 옵션도 엄청나게 다릅니다
Luca C.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.