우리 모두가 알고 있듯이 현재 Git은 분산 버전 관리 분야의 선두주자이며, Git을 중심으로 완전한 생태계가 형성되어 있습니다. Git을 배우기 위해서는 먼저 Git의 기본 작업 흐름을 배우는 것입니다. SVN과 같은 기존 버전 제어 시스템과 비교할 때 Git은 분산 버전 제어를 위해 설계된 강력한 도구입니다. Git을 사용할 때 흔히 사용하는 명령어로는 pull, commit, push 등이 있는데 매우 간단해 보인다. 그러나 때로는 병합 충돌이 발생할 수 있습니다. Git은 충돌을 표시하고 이를 수동으로 해결하도록 요구합니다. 때로는 실수로 코드를 잘못된 브랜치에 커밋하고 원격 저장소에 푸시하는 경우가 있습니다. 다른 브랜치로 전환해야 하는 경우도 있지만 아직 저장되지 않은 변경 사항이 있기 때문에 Git에서는 이를 허용하지 않습니다. 다른 브랜치의 커밋을 통해 코드를 패치해야 한다면 어떻게 해야 할까요? 이 기사에서는 12가지 고급 Git 명령을 소개합니다. 이러한 명령을 올바르게 사용하면 Git 적용 효율성이 크게 향상될 수 있습니다.
1. 병합 대신 리베이스를 사용하여 업스트림 수정 사항을 가져옵니다.
브랜치 병합은 병합 커밋으로 기록되며 이는 매우 의미가 있습니다. 예를 들어, 이는 새로운 기능이 릴리스 분기에 병합되었음을 나타내는 데 사용될 수 있습니다. 그러나 여러 팀 구성원이 프로젝트에서 작업하고 정기적인 git pull을 사용하여 브랜치를 동기화하면 커밋 타임라인이 불필요한 병합 커밋으로 오염됩니다. 더 나은 접근 방식은 git rebase를 사용하여 기능 브랜치를 마스터 브랜치로 리베이스하는 것입니다.
$ git checkout feature $ git rebase master
이렇게 하면 전체 기능 브랜치가 마스터 브랜치의 시작점으로 이동되고 모든 새로운 기능이 병합됩니다. 마스터 브랜치 제출에 대한 변경 사항. 그러나 병합 커밋을 사용하는 것과 비교할 때 리베이스는 원래 브랜치의 각 커밋에 대해 새 커밋을 생성하여 프로젝트 기록을 다시 작성합니다. 리베이스의 주요 이점은 깔끔한 프로젝트 기록을 얻을 수 있다는 것입니다. 또한 여기에는 리베이스의 함정에 대한 몇 가지 논의가 있습니다.
2. git rebase 실행 후 병합 충돌 해결
능력이 높을수록 책임도 크다. git rebase를 수행할 때 병합 충돌이 발생할 수 있습니다. 병합 충돌은 두 커밋이 동일한 파일의 동일한 줄을 수정했으며 Git이 어떤 수정 사항을 적용해야 할지 알 수 없음을 의미합니다. 그러면 다음과 같은 오류 메시지가 나타납니다.
Git에서는 충돌을 일으킨 커밋을 수정할 수 있는 3가지 옵션을 제공합니다(fa39187).
확인 실행 git rebase --abort를 사용하여 리베이스를 완전히 취소합니다. 이렇게 하면 리베이스 변경 사항이 취소되고 브랜치가 git rebase를 실행하기 전의 상태로 돌아갑니다.
git rebase --skip을 실행하면 커밋을 완전히 무시할 수 있습니다. 이렇게 하면 문제의 커밋으로 인해 발생한 변경 사항이 기록에 추가되지 않습니다.
병합 충돌과 동일한 표준 단계를 사용하여 충돌을 해결할 수 있습니다.
3. 수정사항 임시 저장
작업을 진행하다 보면 뭔가 지저분한 상태가 되는 경우가 많습니다. 지금 다른 지점으로 전환해야 하는 경우 어떻게 해야 합니까? 아직 저장되지 않은 변경 사항이 있기 때문에 Git에서는 이 작업을 허용하지 않습니다. 솔직히 말하면, 반쯤 완성된 제품을 제출하고 나중에 수정하고 싶지는 않습니다. 이 문제에 대한 해결책은 git stash 명령을 사용하는 것입니다. Stash는 작업 디렉터리의 현재 상태(예: 수정된 추적 파일 및 스테이징 영역 수정 등)를 수신하여 나중에 언제든지 수정할 수 있도록 완료되지 않은 수정 스택에 저장합니다. 다음 명령을 사용하여 작업을 숨길 수 있습니다.
$ git stash
저장된 작업 디렉터리 및 인덱스 상태 WIP 기능: 3fc175f 경합 조건 수정
HEAD는 이제 3fc175f 경합 조건 수정
이제 작업 디렉토리가 깨끗해졌습니다.
$ git status # On branch feature nothing to commit, working directory clean
이제 안전하게 브랜치를 전환하여 다른 작업을 수행할 수 있습니다. 하지만 걱정하지 마세요. 임시 커밋은 여전히 남아 있습니다.
$ git stash list stash@{0}: WIP on feature: 3fc175f fix race condition
나중에 기능 브랜치로 돌아온 후 모든 임시 변경 사항을 검색할 수 있습니다.
$ git stash pop On branch feature Changes not staged for commit: (use "git add ..." to update what will be committed) modified: index.html Dropped refs/stash@{0} (ac2321cc3a33ba712b8e50c99a99d3c20da9d6b8)
스테이징 관련 , 다음과 같은 몇 가지 다른 옵션을 사용할 수 있습니다.
$ git stash save "describe it" # give the stash a name $ git stash clear # delete a stashed commit $ git stash save --keep-index # stash only unstaged files
4. 특정 원격 브랜치 복제
원격 저장소에서 특정 원격 브랜치를 복제하려는 경우 수행하는 방법 나뭇가지? 일반적으로 git clone을 사용하지만 그렇게 하면 다른 모든 브랜치도 복제됩니다. 편리한 방법은 git 원격 추가를 사용하는 것입니다:
$ git init $ git remote add -t-f origin$ git checkout
5. 체리픽 원격 커밋을 자신의 브랜치에 병합
게다가 원격 저장소만 병합하려는 경우 방법 특정 커밋을 자체 브랜치에 병합하려면? git Cherry-pick을 사용하여 지정된 SHA 값이 있는 커밋을 선택하고 이를 현재 브랜치에 병합할 수 있습니다.
$ git cherry-pick
6. 관련 없는 로컬 저장소에서 패치를 적용합니다
어떻게 해야 합니까? 관련되지 않은 다른 로컬 창고에서 제출된 패치를 현재 창고에 적용해야 하는 경우 어떻게 해야 합니까? 대답은 다음 명령입니다.
$ git --git-dir=/.git format-patch -k -1 --stdout| git am -3 -k
7. 추적 파일의 변경 사항 무시
如果你和你的同事操纵的是相同分支,那么很有可能需要频繁执行git merge或是git rebase。不过,这么做可能会重置一些与环境相关的配置文件,这样在每次合并后都需要修改。与之相反,你可以通过如下命令永久性地告诉Git不要管某个本地文件:
$ git update-index --assume-unchanged
8. 每隔X秒运行一次git pull
通常,合并冲突出现的原因在于你正在工作的本地仓库不再反映远程仓库的当前状态。这正是我们为什么每天早晨要首先执行一次git pull的缘故。此外,你还可以在后台通过脚本(或是使用GNU Screen)每隔X秒调用一次git pull:
$ screen $ for((i=1;i<=10000;i+=1)); do sleep X && git pull; done
9. 将子目录分隔为新的仓库
有时,你可能需要将Git仓库中某个特定的目录转换为一个全新的仓库。这可以通过git filter-branch来实现:
$ git filter-branch --prune-empty --subdirectory-filtermaster # Filter the master branch to your directory and remove empty commits Rewrite 48dc599c80e20527ed902928085e7861e6b3cbe6 (89/89) Ref 'refs/heads/master' was rewritten
现在,仓库会包含指定子目录中的所有文件。虽然之前的所有文件都会被删除,但他们依旧存在于Git历史中。现在可以将新的本地仓库推送到远程了。
10. 清理
有时,Git会提示“untracked working tree files”会“overwritten by checkout”。造成这种情况的原因有很多。不过通常来说,我们可以使用如下命令来保持工作树的整洁,从而防止这种情况的发生:
$ git clean -f # remove untracked files $ git clean -fd # remove untracked files/directories $ git clean -nfd # list all files/directories that would be removed
11. 将项目文件打成tar包,并且排除.git目录
有时,你需要将项目副本提供给无法访问GitHub仓库的外部成员。最简单的方式就是使用tar或zip来打包所有的项目文件。不过,如果不小心,隐藏的.git目录就会包含到tar文件中,这会导致文件体积变大;同时,如果里面的文件与接收者自己的Git仓库弄混了,那就更加令人头疼了。轻松的做法则是自动从tar文件中排除掉.git目录:
$ tar cJf.tar.xz/ --exclude-vcs
12. 查找修改者
最后,如果出现混乱的情况,你一定想要找出是谁造成的。如果生产服务器宕机,那么找到罪魁祸首是比较容易的事情:只需执行git blame。该命令会显示出文件中每一行的作者,提交hash则会找出该行的上一次修改,还能看到提交的时间戳:
$ git blame
当然,Git命令是非常多的,除了上面介绍的12个重要命令外,相信各位InfoQ读者在日常工作过程中也有自己偏爱且好用的一些命令,不妨以评论的形式与其他读者一同分享。