개정 번호에 해당하는 Git은 무엇입니까?


244

우리는 직장에서 SVN을 사용하지만 개인 프로젝트에는 Git을 사용하기로 결정했습니다. 어제 Git을 설치 했는데 Git 과 동일한 개정 번호 가 무엇인지 궁금합니다 .

버전 3.0.8에서 작업하고 모든 버그 수정에이 버그 수정에 대해 이야기 할 때 사용할 수있는 고유 한 개정 번호가 있다고 가정합니다. 따라서 Git의 코드에 3.0.8 태그를 지정하면 수정 번호 또는 다른 더 자세한 식별 유형으로 사용할 수있는 것은 무엇입니까? 인간에게는 해시가 사용자에게 친숙하지 않다는 것을 알았습니다.



가능한 솔루션 중 하나에 대한 기사 가 있습니다. 약간 무거워 보이지만 "git log"출력에 통합되며 "git push / pull / fetch"이외의 추가 명령이 필요하지 않습니다.
Dmitry Pavlenko

불행히도 @DmitryPavlenko의 링크 된 기사는 죽은 도메인에 있습니다 : gitsvn.x10.mx. 주제에 대한 표시가 없으면 다른 곳에서 찾기가 어려울 것입니다.
Michael Donohue

참고 : 더 자세한 설명이 필요없는 설명 : stackoverflow.com/a/41308073/6309
VonC

1
아니요, Laurence Gonsalves, 이것은 "git commit count를 얻는 방법"과 중복되지 않습니다. -이것은 버전 번호에 관한 것이며, 커밋 카운트가 약간 비슷하게 보이도록 할 수 있지만 해시 버전은 커밋 카운트와 매우 다릅니다 :-)
David Svarrer

답변:


149

좋은 소식이든 나쁜 소식이든 해시는 개정 번호입니다. SVN에서 git으로 전환했을 때이 문제가 발생했습니다.

git에서 "태깅"을 사용하여 특정 버전을 특정 버전의 "릴리스"로 태그 지정하여 해당 버전을 쉽게 참조 할 수 있습니다. 이 블로그 게시물을 확인하십시오 .

이해해야 할 핵심은 git은 개정 번호를 가질 수 없다는 것입니다. 사용자 A와 B가 모두 로컬 리포지토리에 커밋하는 경우 어떻게 git이 순차적으로 개정 번호를 할당 할 수 있습니까? A는 서로의 변경 사항을 푸시 / 풀하기 전에 B에 대해 알지 못합니다.

살펴볼 또 다른 사항은 버그 수정 분기의 단순화 된 분기입니다.

릴리스로 시작하십시오 : 3.0.8. 그런 다음 릴리스 후에 다음을 수행하십시오.

git branch bugfixes308

이것은 버그 수정에 대한 분기를 만듭니다. 지점 확인 :

git checkout bugfixes308

이제 원하는 버그 수정을 수행하십시오.

git commit -a

커밋하고 마스터 브랜치로 다시 전환하십시오.

git checkout master

그런 다음 다른 지점에서 변경 사항을 가져옵니다.

git merge bugfixes308

그렇게하면 별도의 릴리스 별 버그 수정 분기가 있지만 여전히 버그 수정 변경 사항을 기본 개발자 트렁크로 가져옵니다.


11
나는 해시가 개정 번호라는 것을 이해했지만 그것이 :-))) 아니기를 바랐다. 매우 훌륭한 설명과 그것을 처리 할 제안에 감사드립니다.
Radek

3
천만에요. SVN에서 처음 집어 들었을 때 git에 매우 좌절했지만 이제는 다른 방향으로 스윙합니다.
makdad

4
또한이 글을 게시한지 오래되었지만 "git branch foo"와 "git checkout foo"를 하나의 라이너로 수행하기 위해 "git checkout -b new_branch_name"을 수행 할 수도 있습니다.
makdad

1
해시가 "진정한"해시이며 심지어 원격 순차도 아닌지 확인하고 있습니까? 따라서 버그 데이터베이스가라고 말하고 fixed in 547cc3e..c4b2eba다른 개정판이 있다면 코드에 수정 사항이 포함되어 있는지 여부를 모릅니다. 분명히 git-central의 자식들은 이것에 대한 해결책을 가지고 있습니까?!?!
Olie

3
SVN에서 r42에서 버그가 수정되었다는 사실은 실제로 분기를 사용하자마자 r43에서도 수정되었는지 여부를 알려주지 않습니다.
Matthieu Moy

186

현대 Git (내 경우 1.8.3.4)을 사용하고 분기를 사용하지 않으면 다음을 수행 할 수 있습니다.

$ git rev-list --count HEAD
68

22
사용 고려git rev-list --count --first-parent HEAD
Flimm

8
이 정보 (번호 68)가 주어지면 코드를 다시 얻기위한 개정판을 결정하는 방법이 있습니까? "개정 68"이 테스트 환경으로 릴리스되고 개발이 계속되고 나중에 개발자가 소스 제어에서 "개정 68"을 다시 획득해야한다고 가정하십시오. 특정 버전을 복제 대상으로 지정하는 방법은 무엇입니까? 아니면 이것을 불필요하게 만드는 Git에 대해 뭔가 빠졌습니까?
David

9
이 솔루션은 개발자마다 결과가 다릅니다. 또한 "카운트"에서 커밋으로 거꾸로 계산하면 개발자마다 다른 커밋이 생성됩니다 !! 이것은 Git의 분산 특성으로 인해 커밋이 동일한 시간 동안 다른 리포지토리에서 발생하지만 git rev-list --count HEAD마지막 푸시 및 풀 시간에 따라 계산되지 않을 수 있습니다 .
Jason

2
@Jason, David의 의견 추가에 대한 의견이 --first-parent문제를 해결합니까? 똑같이 간단한 해결 방법이 있거나 더 강력하게 만드는 방법이있는 경우 드문 경우로 인해 가장 간단한 솔루션을 피하는 것이 싫습니다.
MarkHu 2019

4
@MarkHu가 --first-parent도와드립니다. 리베이스가 수행되지 않고 동일한 브랜치가 항상 릴리스를 만드는 데 사용되는 한 (물론이 릴리스 번호를 계산하는 한) 이것이 사용될 수 있다고 생각합니다. 그래도 릴리스가 시작된 커밋을 항상 고유하게 식별할지는 확실하지 않습니다. 여기에 잘못 될 수있는 많은 것들이 있습니다 ... 그러나 지금은 이것을 분명히 깨뜨릴 수있는 어떤 것도 생각할 수 없습니다 (위의 "길이와 같은"진술이 주어짐). git describe다른 답변에서 언급 한 방법은 갈 수있는 방법입니다. 사람이 읽을 수있는 것을 원하면 태그를 만드십시오.
Jason

104

git describe명령은 특정 커밋을 나타내는 약간 더 읽기 쉬운 이름을 만듭니다. 예를 들어, 설명서에서 :

git.git 현재 트리와 같은 것으로 다음을 얻습니다.

[torvalds@g5 git]$ git describe parent
v1.0.4-14-g2414721

즉, "부모"브랜치의 현재 헤드는 v1.0.4를 기반으로하지만 그 위에 몇 개의 커밋이 있기 때문에, 추가 커밋 수 ( "14")와 커밋에 대한 약식 객체 이름을 추가했습니다. 끝에 자체 ( "2414721")가 있습니다.

현명하게 이름이 지정된 태그를 사용하여 특정 릴리스에 태그를 지정하면 SVN "개정 번호"와 거의 같은 것으로 간주 될 수 있습니다.


7
리포지토리에 이미 태그가있는 경우 에만 작동 git합니다. 그렇지 않으면 "치명적 : 이름을 찾을 수 없습니다. -스택 오버플로 ; 태그를 직접 설정해야한다는 의미입니다.
sdaau

14
@ sdaau : 스크립트 또는 다른 것으로 이것을 git describe사용하고 절대 실패하지 않으 려면 git describe --always옵션을 사용하십시오 .
Greg Hewgill

git describe소스 커밋을 찾기 위해 출력을 사용할 수 있습니까 ? 로그에서 커밋을 수동으로 계산하는 것이 부족하다는 의미입니다.
Lii

@Lii : "소스 커밋"은 무엇을 의미합니까? 가장 가까운 태그 ( v1.0.4)와 가장 최근의 커밋 ID ( 2414721)는 이미 git describe 출력의 일부입니다.
Greg Hewgill

@GregHewgill : 예, 질문을했을 때 "축약 된 객체 이름" 이 커밋을 식별하는 데 사용할 수있는 값 이라는 것을 몰랐습니다 . 훌륭합니다!
Lii

67

다른 포스터는 옳습니다. "개정 번호"는 없습니다.

가장 좋은 방법은 "릴리스"에 태그를 사용하는 것입니다!

그러나 나는 다음을 사용하여 수정 번호가짜 로 만들었습니다 (클라이언트는 수정 버전과 진행 상황을 볼 수 있습니다.

다음을 사용하여 "HEAD"의 "현재 개정판"을 시뮬레이션합니다.

git rev-list HEAD | wc -l

그러나 클라이언트가 "개정"1302에 버그가 있다고하면 어떻게해야합니까?

이를 위해 ~ / .gitconfig의 [alias] 섹션에 다음을 추가했습니다.

show-rev-number = !sh -c 'git rev-list --reverse HEAD | nl | awk \"{ if(\\$1 == "$0") { print \\$2 }}\"'

를 사용 하여 "개정"에 대한 해시git show-rev-number 1302인쇄합니다. :)

나는 얼마 전에 그 "기술"에 대해 블로그 포스트 (독일어)를 만들었습니다 .


@Radek- "때때로 'code change = commit'가 무엇을 고쳤는지 알아야합니다."-그러면 git bisect(link) 는 누가 언제 변경했는지를 식별하는 적절한 도구입니다.
마이클

@Radek 네, 계속 증가하고 있습니다. HEAD에서 체크인 한 개정판 만 계산합니다. 따라서 모든 커밋은 새로운 개정입니다. 다른 지점에서는 작동하지 않습니다.
OderWat

1
나는 당신의 해결책을 좋아합니다. 단순화 할 수 있습니다 : show-rev-number =! sh -c 'git rev-list --reverse HEAD | awk NR == $ 0 '
avner

@avner 감사합니다! 나는 분명히 내 인생에서 많은 awk를 사용하지 않았다 :)
OderWat

3
나는 사용해야했다git rev-list --reverse HEAD | awk "{ print NR }" | tail -n 1
Gerry

27

Git은 Subversion과 동일한 개정 번호 개념을 가지고 있지 않습니다. 대신 커밋으로 만들어진 각 스냅 샷은 SHA1 체크섬으로 태그가 지정됩니다. 왜? 분산 버전 제어 시스템에서 revno를 실행하는 데 몇 가지 문제점이 있습니다.

첫째, 개발은 전혀 선형 적이 지 않기 때문에, 숫자를 첨부하는 것은 프로그래머로서의 요구를 만족시키는 방식으로 해결하기 어려운 문제입니다. 숫자를 추가하여이 문제를 해결하려고하면 숫자가 예상대로 작동하지 않을 때 빠르게 문제가 될 수 있습니다.

둘째, 개정 번호는 다른 머신에서 생성 될 수 있습니다. 이는 특히 연결이 단방향이기 때문에 숫자 동기화를 훨씬 어렵게 만듭니다. 리포지토리가있는 모든 시스템에 액세스하지 못할 수도 있습니다.

셋째는, 자식에 다소 지금 소멸 OpenCM 시스템에 의해 개척의 정체성 커밋의합니다 (이 커밋 것)의에 해당 이름을 합니다 (SHA 아이디). 이 명명 = 정체성 개념은 매우 강력합니다. 커밋 이름을 가지고 앉아 있으면 커밋을 위조 할 수없는 방식으로 식별합니다. 결과적으로 모든 커밋을 첫 번째 초기 커밋으로 다시 확인할 수 있습니다. 하여 git fsck명령이 손상 .

우리는 개정의 DAG (방향성 비순환 그래프)가 이러한 현재 트리를 구성하기 때문에 이제, 우리는 해결하기 위해 어떤 도구가 필요합니다 당신의 문제를 우리가 서로 다른 버전을 식별하려면 어떻게합니까. 주어진 접두사 1516bd가 커밋을 고유하게 식별 하는 경우 먼저 해시의 일부를 생략 할 수 있습니다 . 그러나 이것은 또한 오히려 고안되었습니다. 대신, 트릭은 태그 및 / 또는 분기를 사용하는 것입니다. 태그 또는 브랜치는 지정된 커밋 SHA1-id에 첨부하는 "노란색 메모"와 유사합니다. 본질적으로 태그는 움직이지 않는 것을 의미하지만 새로운 커밋이 HEAD에 이루어지면 지점이 움직입니다. 태그 나 브랜치를 커밋하는 방법은 git-rev-parse의 매뉴얼 페이지를 참조하십시오.

일반적으로 특정 코드 조각에 대해 작업해야하는 경우 해당 조각이 변경 되고 있으므로 말하는 주제 이름이있는 분기 여야합니다. 많은 브랜치를 생성하는 것은 (프로그래머 당 20-30 명의 사람들은 들어 본 적이 없으며, 다른 사람들이 작업 할 수 있도록 게시 된 4-5 명은) 효과적인 git의 트릭입니다. 모든 작업은 자체 분기로 시작한 다음 테스트 될 때 병합되어야합니다. 게시되지 않은 브랜치는 완전히 다시 쓸 수 있으며 역사를 파괴하는이 부분은 git의 힘입니다.

변화가 마스터받아 들여 지면 다소 얼어 붙어 고고학이됩니다. 이 시점에서 태그를 지정할 수 있지만 sha1 합계를 통해 버그 커커 나 이슈 트래커에서 특정 커밋에 대한 참조가 더 자주 이루어집니다. 태그는 유지 관리 분기 (이전 버전)의 버전 범프 및 분기 지점 용으로 예약되는 경향이 있습니다.


18

관심이 있으시면 여기 git infos 에서 자동으로 버전 번호를 형식으로 관리했습니다.

<major>.<minor>.<patch>-b<build>

여기서 build는 총 커밋 수입니다. 에 흥미로운 코드가 표시 Makefile됩니다. 버전 번호의 다른 부분에 액세스하는 관련 부분은 다음과 같습니다.

LAST_TAG_COMMIT = $(shell git rev-list --tags --max-count=1)
LAST_TAG = $(shell git describe --tags $(LAST_TAG_COMMIT) )
TAG_PREFIX = "latex-tutorial-v"

VERSION  = $(shell head VERSION)
# OR try to guess directly from the last git tag
#VERSION    = $(shell  git describe --tags $(LAST_TAG_COMMIT) | sed "s/^$(TAG_PREFIX)//")
MAJOR      = $(shell echo $(VERSION) | sed "s/^\([0-9]*\).*/\1/")
MINOR      = $(shell echo $(VERSION) | sed "s/[0-9]*\.\([0-9]*\).*/\1/")
PATCH      = $(shell echo $(VERSION) | sed "s/[0-9]*\.[0-9]*\.\([0-9]*\).*/\1/")
# total number of commits       
BUILD      = $(shell git log --oneline | wc -l | sed -e "s/[ \t]*//g")

#REVISION   = $(shell git rev-list $(LAST_TAG).. --count)
#ROOTDIR    = $(shell git rev-parse --show-toplevel)
NEXT_MAJOR_VERSION = $(shell expr $(MAJOR) + 1).0.0-b$(BUILD)
NEXT_MINOR_VERSION = $(MAJOR).$(shell expr $(MINOR) + 1).0-b$(BUILD)
NEXT_PATCH_VERSION = $(MAJOR).$(MINOR).$(shell expr $(PATCH) + 1)-b$(BUILD)

9

배쉬 기능 :

git_rev ()
{
    d=`date +%Y%m%d`
    c=`git rev-list --full-history --all --abbrev-commit | wc -l | sed -e 's/^ *//'`
    h=`git rev-list --full-history --all --abbrev-commit | head -1`
    echo ${c}:${h}:${d}
}

다음과 같은 출력

$ git_rev
2:0f8e14e:20130220

그건

commit_count:last_abbrev_commit:date_YYmmdd

그런 종류의 것이 유용 할 수 있지만 증분 버전 번호에 관심이 있다면 필드 위치를 바꾸어 (증분이 아닌) 해시가 마지막이됩니다.
MarkHu

8

커밋SHA1 해시 는 Subversion 개정 번호와 같습니다.


7
불행히도 개정 번호와는 상당히 다른 속성을 가지고 있습니다. 다소 길며 단조롭게 증가하지 않습니다. 그것이 배포를 위해 지불 할 가격 인 것
같아요

1
@ CodeInChaos : 나는 당신이 얻는 것을 알고 있지만 일반적으로 해시 코드의 처음 6 또는 8 문자로 git commit을 참조하는 것이 가능합니다.
Chris Pitman

5
@ Radek : 그들은 독특하게 보장되지는 않습니다 (충돌을 발견하면 약간의 유명 인사를 얻을 수 있습니다).
Slartibartfast

8
@Radek en.wikipedia.org/wiki/Collision_attack 에 따르면 , 4 개의 해시 문자는 16 비트 ID를 가지며 이는 256 (= 2 ^ (16/2)) 커밋이있는 리포지토리에는 50 개의 커밋이 있음을 의미합니다 두 커밋이 같은 4 문자 접두사를 가질 확률 % (그리고 65536 커밋을 사용하면 4 문자 ID 범위가 소진되므로 확실합니다). 하나의 문자를 추가하면 20 비트 ID가 있으며 이는 50 % 임계 값이 1024 커밋에 있음을 의미합니다. 그러나 이것은 통계적 매개 변수이므로 그러한 충돌이 더 일찍 발생하지 않는다는 보장은 없습니다.
Rudi

2
해시는 내용을 기반으로하기 때문에 두 커밋이 확실하지 않은 동일한 해시 접두사를 가질 가능성은 여전히 ​​있습니다. 65536 커밋에서 두 개는 동일한 4 문자 접두사를 가질 가능성이 높지만 여전히 확실하지는 않습니다. 옆으로, 전체 해시는 아직 충돌이 없지만 git이 작업 중입니다 :) stackoverflow.com/questions/3475648/…
goodeye

6

이것은 다른 솔루션을 기반으로 내 makefile에서 수행 한 작업입니다. 이렇게하면 코드에 개정 번호가 부여 될뿐만 아니라 릴리스를 다시 작성할 수있는 해시도 추가됩니다.

# Set the source control revision similar to subversion to use in 'c'
# files as a define.
# You must build in the master branch otherwise the build branch will
# be prepended to the revision and/or "dirty" appended. This is to
# clearly ID developer builds.
REPO_REVISION_:=$(shell git rev-list HEAD --count)
BUILD_BRANCH:=$(shell git rev-parse --abbrev-ref HEAD)
BUILD_REV_ID:=$(shell git rev-parse HEAD)
BUILD_REV_ID_SHORT:=$(shell git describe --long --tags --dirty --always)
ifeq ($(BUILD_BRANCH), master)
REPO_REVISION:=$(REPO_REVISION_)_g$(BUILD_REV_ID_SHORT)
else
REPO_REVISION:=$(BUILD_BRANCH)_$(REPO_REVISION_)_r$(BUILD_REV_ID_SHORT)
endif
export REPO_REVISION
export BUILD_BRANCH
export BUILD_REV_ID

3
git-describe오류를 피하기 위해 사용하는 가장 안전한 방법 은 git describe --always --dirty --long --tags내가 생각할 수있는 모든 경우에 작동하는 것입니다.
MarkHu

5

빌드 번호로 git 해시를 사용하는 문제는 단조롭게 증가하지 않는다는 것입니다. OSGi는 빌드 번호에 타임 스탬프를 사용할 것을 제안합니다. Subversion 또는 perforce 변경 번호 대신 지점에 대한 커밋 수를 사용할 수 있습니다.


5

Git에서 버전 정보를 검색하고 태그 지정을 단순화하는 일부 PowerShell 유틸리티를 작성했습니다.

함수 : Get-LastVersion, Get-Revision, Get-NextMajorVersion, Get-NextMinorVersion, TagNextMajorVersion, TagNextMinorVersion :

# Returns the last version by analysing existing tags,
# assumes an initial tag is present, and
# assumes tags are named v{major}.{minor}.[{revision}]
#
function Get-LastVersion(){
  $lastTagCommit = git rev-list --tags --max-count=1
  $lastTag = git describe --tags $lastTagCommit
  $tagPrefix = "v"
  $versionString = $lastTag -replace "$tagPrefix", ""
  Write-Host -NoNewline "last tagged commit "
  Write-Host -NoNewline -ForegroundColor "yellow" $lastTag
  Write-Host -NoNewline " revision "
  Write-Host -ForegroundColor "yellow" "$lastTagCommit"
  [reflection.assembly]::LoadWithPartialName("System.Version")

  $version = New-Object System.Version($versionString)
  return $version;
}

# Returns current revision by counting the number of commits to HEAD
function Get-Revision(){
   $lastTagCommit = git rev-list HEAD
   $revs  = git rev-list $lastTagCommit |  Measure-Object -Line
   return $revs.Lines
}

# Returns the next major version {major}.{minor}.{revision}
function Get-NextMajorVersion(){
    $version = Get-LastVersion;
    [reflection.assembly]::LoadWithPartialName("System.Version")
    [int] $major = $version.Major+1;
    $rev = Get-Revision
    $nextMajor = New-Object System.Version($major, 0, $rev);
    return $nextMajor;
}

# Returns the next minor version {major}.{minor}.{revision}
function Get-NextMinorVersion(){
    $version = Get-LastVersion;
    [reflection.assembly]::LoadWithPartialName("System.Version")
    [int] $minor = $version.Minor+1;
    $rev = Get-Revision
    $next = New-Object System.Version($version.Major, $minor, $rev);
    return $next;
}

# Creates a tag with the next minor version
function TagNextMinorVersion($tagMessage){
    $version = Get-NextMinorVersion;
    $tagName = "v{0}" -f "$version".Trim();
    Write-Host -NoNewline "Tagging next minor version to ";
    Write-Host -ForegroundColor DarkYellow "$tagName";
    git tag -a $tagName -m $tagMessage
}

# Creates a tag with the next major version (minor version starts again at 0)
function TagNextMajorVersion($tagMessage){
    $version = Get-NextMajorVersion;
    $tagName = "v{0}" -f "$version".Trim();
    Write-Host -NoNewline "Tagging next majo version to ";
    Write-Host -ForegroundColor DarkYellow "$tagName";
    git tag -a $tagName -m $tagMessage
}

4

각 커밋에는 고유 한 해시가 있습니다. 그 외에는 git에 개정 번호가 없습니다. 사용자 친 화성을 높이려면 커밋에 태그를 추가해야합니다.


3

나는 다른 가능한 방법을 참고하는 것처럼 - 그것은 사용하는 것입니다 git 자식 노트 (1) V 1.6.6 (이후 존재, 자기에 주 - 힘내 ) (내가 사용 git버전 1.7.9.5 참조).

기본적으로 git svn선형 히스토리 (표준 레이아웃, 브랜치, 태그 없음)를 사용 하여 SVN 저장소를 복제하고 복제 된 git저장소 에서 개정 번호를 비교하려고했습니다 . 이 git clone에는 기본적으로 태그가 없으므로 사용할 수 없습니다 git describe. 여기서 전략은 선형 이력에만 효과적 일 것입니다-병합 등으로 어떻게 될지 확실하지 않습니다. 그러나 기본 전략은 다음과 같습니다.

  • git rev-list모든 커밋 히스토리 목록 요청
    • rev-list기본적으로 "역순으로"역순 이므로 --reverse스위치를 사용하여 가장 오래된 항목으로 정렬 된 커밋 목록을 가져옵니다.
  • bash쉘을 사용 하여
    • 각 커밋마다 카운터 카운터를 개정 카운터로 늘리십시오.
    • 각 커밋마다 "임시"자식 메모 생성 및 추가
  • 그런 다음 git logwith 을 사용하여 로그를 찾아보십시오. --notes이 경우 커밋 노트도 덤프됩니다.이 경우 "개정 번호"가됩니다.
  • 완료되면 임시 메모를 삭제합니다 ( NB :이 메모가 커밋되었는지 확실하지 않습니다. 실제로 표시되지 않음git status )

먼저, git기본 메모 위치를 가짐에 유의하십시오. 그러나 메모에 대해 ref(erence)를 지정할 수도 있습니다 .git. 예를 들어, gitrepo 폴더 에있는 동안 git notes get-ref어떤 디렉토리가 될지를 호출 할 수 있습니다.

$ git notes get-ref
refs/notes/commits
$ git notes --ref=whatever get-ref
refs/notes/whatever

주목해야 할 점은 경우이다 notes addA를 --ref, 그렇지 않으면 당신은 같은 오류가 발생할 수 있습니다 "-, 당신은 또한 나중에 다시 참조를 사용해야 없음 참고 개체 XXX을 찾을 수 없습니다 ... ".

이 예제에서는 ref노트를 "linrev"(선형 개정의 경우)라고 부르기로 선택했습니다. 이는 절차가 기존의 노트를 방해 할 가능성도 없다는 것을 의미합니다. 나는 또한 초보자 --git-dir이기 때문에 스위치를 사용하고 있는데 , git그것을 이해하는 데 약간의 문제가있었습니다. 그래서 "나중에 기억하고 싶습니다" :); 또한 사용할 때 --no-pager생성을 억제 하는 데 less사용 git log합니다.

따라서 디렉토리에 myrepo_git있고 git저장소 인 하위 폴더가 있다고 가정 합니다. 하나는 할 수 있습니다 :

### check for already existing notes:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.

### iterate through rev-list three, oldest first,
### create a cmdline adding a revision count as note to each revision

$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
  TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
  TCMD="$TCMD add $ih -m \"(r$((++ix)))\""; \
  echo "$TCMD"; \
  eval "$TCMD"; \
done

# git --git-dir=./myrepo_git/.git notes --ref linrev add 6886bbb7be18e63fc4be68ba41917b48f02e09d7 -m "(r1)"
# git --git-dir=./myrepo_git/.git notes --ref linrev add f34910dbeeee33a40806d29dd956062d6ab3ad97 -m "(r2)"
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev add 04051f98ece25cff67e62d13c548dacbee6c1e33 -m "(r15)"

### check status - adding notes seem to not affect it:

$ cd myrepo_git/
$ git status
# # On branch master
# nothing to commit (working directory clean)
$ cd ../

### check notes again:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# (r15)

### note is saved - now let's issue a `git log` command, using a format string and notes:

$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)
# 77f3902: _user_: Sun Apr 21 18:29:00 2013 +0000:  >>test message 14<< (r14)
# ...
# 6886bbb: _user_: Sun Apr 21 17:11:52 2013 +0000:  >>initial test message 1<< (r1)

### test git log with range:

$ git --git-dir=./myrepo_git/.git --no-pager log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
# 04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)

### erase notes - again must iterate through rev-list

$ ix=0; for ih in $(git --git-dir=./myrepo_git/.git rev-list --reverse HEAD); do \
  TCMD="git --git-dir=./myrepo_git/.git notes --ref linrev"; \
  TCMD="$TCMD remove $ih"; \
  echo "$TCMD"; \
  eval "$TCMD"; \
done
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# Removing note for object 6886bbb7be18e63fc4be68ba41917b48f02e09d7
# git --git-dir=./myrepo_git/.git notes --ref linrev remove f34910dbeeee33a40806d29dd956062d6ab3ad97
# Removing note for object f34910dbeeee33a40806d29dd956062d6ab3ad97
# ...
# git --git-dir=./myrepo_git/.git notes --ref linrev remove 04051f98ece25cff67e62d13c548dacbee6c1e33
# Removing note for object 04051f98ece25cff67e62d13c548dacbee6c1e33

### check notes again:

$ git --git-dir=./myrepo_git/.git notes show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.
$ git --git-dir=./myrepo_git/.git notes --ref=linrev show
# error: No note found for object 04051f98ece25cff67e62d13c548dacbee6c1e33.

따라서 적어도 분기가없는 완전 선형 이력의 특정 경우에는 개정 번호 가이 접근법과 일치하는 것 같습니다. 또한이 접근법은 git log개정 범위와 함께 사용할 수 있지만 올바른 개정 번호를 계속 얻을 수있는 것 같습니다 -YMMV 그러나 다른 맥락에서 ...

이것이 누군가를 돕기를 바랍니다,
건배!


편집 : 좋아, 여기 git에 위의 루프에 대한 별칭이 있고 setlinrev, unsetlinrev; git 저장소 폴더에있을 때 ( 불쾌한 bash탈출을 참고 하십시오. # 16136745-세미콜론을 포함하는 Git 별칭 추가 ) :

cat >> .git/config <<"EOF"
[alias]
  setlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
      TCMD=\"git notes --ref linrev\"; \n\
      TCMD=\"$TCMD add $ih -m \\\"(r\\$((++ix)))\\\"\"; \n\
      #echo \"$TCMD\"; \n\
      eval \"$TCMD\"; \n\
    done; \n\
    echo \"Linear revision notes are set.\" '"

  unsetlinrev = "!bash -c 'ix=0; for ih in $(git rev-list --reverse HEAD); do \n\
      TCMD=\"git notes --ref linrev\"; \n\
      TCMD=\"$TCMD remove $ih\"; \n\
      #echo \"$TCMD\"; \n\
      eval \"$TCMD 2>/dev/null\"; \n\
    done; \n\
    echo \"Linear revision notes are unset.\" '"
EOF

... 따라서 git setlinrev리니어 리비전 노트와 관련된 로그를 작성하기 전에 간단히 호출 할 수 있습니다 . 그리고 git unsetlinrev그 메모를 삭제하면 완료 할 때; git repo 디렉토리 내부의 예 :

$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 <<

$ git setlinrev
Linear revision notes are set.
$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 << (r15)
$ git unsetlinrev
Linear revision notes are unset.

$ git log --notes=linrev --format=format:"%h: %an: %ad:  >>%s<< %N" HEAD^..HEAD
04051f9: _user_: Sun Apr 21 18:29:02 2013 +0000:  >>test message 15 <<

쉘이 이러한 별명을 완료하는 데 걸리는 시간은 저장소 히스토리의 크기에 따라 다릅니다.


2

있는 사람들을 위해 앤트 빌드 프로세스를,이 목표와 자식에 프로젝트의 버전 번호를 생성 할 수 있습니다 :

<target name="generate-version">

    <exec executable="git" outputproperty="version.revisions">
        <arg value="log"/>
        <arg value="--oneline"/>
    </exec>

    <resourcecount property="version.revision" count="0" when="eq">
        <tokens>
            <concat>
                <filterchain>
                    <tokenfilter>
                        <stringtokenizer delims="\r" />
                    </tokenfilter>
                </filterchain>
            <propertyresource name="version.revisions" />
            </concat>
        </tokens>
    </resourcecount>
    <echo>Revision : ${version.revision}</echo>

    <exec executable="git" outputproperty="version.hash">
        <arg value="rev-parse"/>
        <arg value="--short"/>
        <arg value="HEAD"/>
    </exec>
    <echo>Hash : ${version.hash}</echo>


    <exec executable="git" outputproperty="version.branch">
        <arg value="rev-parse"/>
        <arg value="--abbrev-ref"/>
        <arg value="HEAD"/>
    </exec>
    <echo>Branch : ${version.branch}</echo>

    <exec executable="git" outputproperty="version.diff">
        <arg value="diff"/>
    </exec>

    <condition property="version.dirty" value="" else="-dirty">
        <equals arg1="${version.diff}" arg2=""/>
    </condition>

    <tstamp>
        <format property="version.date" pattern="yyyy-mm-dd.HH:mm:ss" locale="en,US"/>
    </tstamp>
    <echo>Date : ${version.date}</echo>

    <property name="version" value="${version.revision}.${version.hash}.${version.branch}${version.dirty}.${version.date}" />

    <echo>Version : ${version}</echo>

    <echo file="version.properties" append="false">version = ${version}</echo>

</target>

결과는 다음과 같습니다.

generate-version:
    [echo] Generate version
    [echo] Revision : 47
    [echo] Hash : 2af0b99
    [echo] Branch : master
    [echo] Date : 2015-04-20.15:04:03
    [echo] Version : 47.2af0b99.master-dirty.2015-04-20.15:04:03

버전 번호를 생성 할 때 파일이 커밋되지 않은 경우 더티 플래그가 나타납니다. 일반적으로 응용 프로그램을 빌드 / 패키징 할 때 모든 코드 수정은 리포지토리에 있어야합니다.


1

커밋의 SHA-1 ID와 함께 서버 시간의 날짜와 시간이 도움이 되었습니까?

이 같은:

커밋은 2013 년 8 월 19 일 11:30:25에 6886bbb7be18e63fc4be68ba41917b48f02e09d7_19aug2013_113025로 표시됩니다.


1

Git 매뉴얼에서 태그는이 문제에 대한 훌륭한 답변입니다.

Git에서 주석이 달린 태그를 만드는 것은 간단합니다. 가장 쉬운 방법은 tag 명령을 실행할 때 -a를 지정하는 것입니다.

$ git tag -a v1.4 -m 'my version 1.4'

$ git tag
v0.1
v1.3
v1.4

2.6 Git 기본 사항 확인 -태그 지정


너무 By default, the git push command doesn’t transfer tags to remote servers.
나쁘면

1

우리는 이 명령을 사용하여 git에서 버전과 개정판을 얻습니다.

git describe --always --tags --dirty

반환

  • 어떤 태그가 사용되지 않을 때 리비전 해시 커밋 (예 gcc7b71f)
  • 태그에있을 때 버전으로 태그 이름 (예 : v2.1.0릴리스에 사용)
  • 태그 이름, 마지막 태그 이후 개정 번호 (예 : 때 태그 다음에 해시를 커밋 v5.3.0-88-gcc7b71f)
  • 동일한 (예를 들면 상기 플러스 작업 트리 로컬 변경이있는 경우에 "더티"태그 등 v5.3.0-88-gcc7b71f-dirty)

참조 : https://www.git-scm.com/docs/git-describe#Documentation/git-describe.txt


0

Visual Studio의 빌드 후 이벤트

echo  >RevisionNumber.cs static class Git { public static int RevisionNumber =
git  >>RevisionNumber.cs rev-list --count HEAD
echo >>RevisionNumber.cs ; }

-1

사용을 고려하십시오

git-rev-label

Git 저장소 개정판에 대한 정보를 다음과 같은 형식으로 제공합니다 master-c73-gabc6bec. 환경 변수와 Git의 정보로 템플릿 문자열 또는 파일을 채울 수 있습니다. 분기, 태그, 커밋 해시, 커밋 횟수, 더티 상태, 날짜 및 시간 등 프로그램 버전에 대한 정보를 제공하는 데 유용합니다. 가장 유용한 것 중 하나는 커밋 횟수이며 병합 된 분기를 고려하지 않고 첫 번째 상위 항목입니다.

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