참고 : Git과 Mercurial의 가장 큰 차이점 중 하나는 인덱스 또는 스테이징 영역 의 명시 적 존재입니다 .
에서 힘내 사용자에 대한 의욕 :
Git은 인덱스 또는 스테이징 영역의 개념을 노출 하는 유일한 DistributedSCM 입니다. 다른 사용자는이를 구현하고 숨길 수 있지만 다른 경우에는 사용자가 인식하거나 처리 할 필요가 없습니다.
Mercurial의 대략적인 DirState
기능은 다음 커밋에 포함될 파일을 결정하기 위해 작업 복사본 상태 정보를 제어하는입니다. 그러나 어쨌든이 파일은 자동으로 처리됩니다.
또한 커밋 할 파일을 명령 줄에서 지정하거나 다음을 사용하여 커밋 할 때 더 선택적으로 할 수 있습니다.RecordExtension
.
인덱스를 다루는 것이 불편하다면 더 나은쪽으로 전환하는 것입니다 ;-)
트릭은 Git을 완전히 활용하기 위해 인덱스를 이해해야한다는 것입니다. 2006 년 5 월 의이 기사는 그때 우리에게 상기시켜줍니다 (지금도 여전히 사실입니다).
"인덱스를 거부하면 실제로 자식 자체를 거부하는 것입니다."
이제이 기사에는 사용하기가 더 간단한 명령이 많이 포함되어 있지만 (컨텐츠에 너무 많이 의존하지 마십시오.)), 일반적인 아이디어는 그대로 유지됩니다.
새 기능을 작업 중이며 파일을 약간 수정하기 시작합니다.
# working, add a few lines
$ git add myFile
# working, another minor modification
$ git add myFile
이 시점에서 다음 커밋은 현재 브랜치에서 2 개의 사소한 수정을 시작합니다.
# working, making major modification for the new features
# ... damn! I cannot commit all this in the current branch: nothing would work
$ git commit
이 시점에서 스테이징 영역 (색인)에 추가 된 변경 사항 만 기록하고 현재 작업 디렉토리에 표시되는 주요 변경 사항은 기록하지 않습니다.
$ git branch newFeature_Branch
$ git add myFile
다음 커밋은 새 브랜치 'newFrature_Branch'의 다른 모든 주요 변경 사항을 기록합니다.
이제 대화 형으로 추가하거나 커밋을 분할하는 것도 Mercurial에서 ' hg record
'명령 또는 기타 확장을 통해 사용할 수있는 기능 입니다. RecordExtension
, 또는 CrecordExtension
.
그러나 이것은 Mercurial의 일반적인 작업 흐름의 일부가 아닙니다.
Git은 커밋을 일련의 " 파일 내용 변경"으로보고 이러한 변경 사항을 한 번에 하나씩 추가 할 수 있습니다.
해당 기능과 그 결과를 연구해야합니다. 대부분의 Git 기능 (예 : 병합 을 쉽게 되돌 리거나 문제를 양분하거나 커밋을 되 돌리는 기능) , 의욕 반대 )이 "파일 내용"패러다임에서 비롯됩니다.
tonfa (프로필 : "Hg dev, pythonist": 수치 ...) 댓글에서
인덱스에는 근본적으로 "git-ish"가 없습니다. hg는 가치가 있다고 판단되면 인덱스를 사용할 수 있습니다. mq
되거나 또는 shelve
이미 일부를 수행 .
오 소년. 다시 간다.
첫째, 저는 한 도구가 다른 도구보다 더 멋지게 보이도록 여기에 온 것이 아닙니다. 나는 Hg가 훌륭하고 매우 직관적이며 좋은 지원을 받는다는 것을 알게되었다 (특히 Windows, 나의 메인 플랫폼에서, 비록 내가 Linux와 Solaris8 또는 10에서도 작업하지만).
인덱스는 실제로 Linus Torvalds가 VCS와 함께 작동 하는 방식에서 전면 중앙입니다 .
Git은 첫 번째 병합을 수행하기 전에도 1 일차부터 명시 적 인덱스 업데이트를 사용했습니다. 단순히 제가 항상 일해 왔던 방식입니다. 나는 다음 버전을위한 Makefile 업데이트이기 때문에 커밋하고 싶지 않은 내 트리에 임의의 패치가있는 더러운 트리를 갖는 경향이 있습니다.
이제 조합 , (단 힘내에서 본 개념없는) 인덱스 와 패러다임 그것을 만드는 "내용 왕은" 매우 독특하고 "자식 틱을" :
git은 콘텐츠 추적기 이며 파일 이름은 콘텐츠와 연결되지 않는 한 의미가 없습니다. 따라서 git add filename의 유일한 정상적인 동작은 파일의 내용과 파일 이름을 색인에 추가하는 것입니다.
참고 : 여기서 "콘텐츠"는 다음과 같이 정의됩니다 .
Git의 인덱스는 기본적으로 다음과 같이 정의됩니다.
- 트리 의 전체 " 내용 " 을 포함하기에 충분합니다 ( 여기에는 모든 메타 데이터가 포함됩니다. 파일 이름, 모드 및 파일 내용은 모두 "내용"의 일부 이며 그 자체로는 의미가 없습니다!) )
- 명백하고 사소한 (그러나 매우 중요합니다!) 파일 시스템 비교 최적화를 허용하는 추가 "stat"정보.
따라서 인덱스 가 콘텐츠 로 표시 되어야 합니다 .
내용은 별도의 부분 인 "파일 이름"또는 "파일 내용"이 아닙니다. 당신은 정말로 둘을 분리 할 수 없습니다 .
파일 이름 자체는 의미가 없으며 (파일 콘텐츠도 있어야 함) 파일 콘텐츠 자체는 의미가 없습니다 (연결 방법을 알아야 함).
내가 말하려는 것은 git은 근본적 으로 내용이없는 파일 이름을 볼 수 있도록 허용 하지 않는다는 것입니다. 전체 개념은 미쳤고 유효하지 않습니다. "현실"과는 관련이 없습니다.
에서 자주 묻는 질문 , 주요 장점은 다음과 같습니다 :
- 세밀하게 커밋하다
- 합리적으로 오랫동안 트리에서 커밋되지 않은 수정을 유지하도록 도와줍니다.
- 하나의 커밋에 대해 당신이 무슨 짓을했는지 확인, 여러 개의 작은 단계를 수행
git diff
하고, 각 작은 단계를 검증 git add
하거나 git add -u
.
- 병합 충돌의 우수한 관리 할 수 있습니다 :
git diff --base
, git diff --ours
, git diff --theirs
.
git commit --amend
그 동안 색인이 수정되지 않은 경우 로그 메시지 만 수정할 수 있습니다.
개인적으로이 동작이 기본값이되어서는 안된다고 생각합니다. 사람들이 테스트되거나 적어도 컴파일 된 것을 커밋하기를 원합니다.
일반적으로 ( "테스트 또는 컴파일 된"부분에 대해) Git에서 분기 및 병합 (체리 선택 또는 리베이스)을 허용하는 방식을 사용하면 임시 개인 브랜치에서 원하는만큼 커밋 할 수 있습니다 (푸시 전용 원격 "백업"저장소로), 모든 올바른 테스트가 준비된 상태에서 공용 브랜치에서 "추악한 커밋"을 다시 수행합니다.