為了紀念 Git 的 13 歲生日,這裡有 13 個技巧和訣竅來讓你的 Git 經驗更加有用和強大。從你可能忽略的一些基本知識開始,並擴展到一些真正的高級用戶技巧!
當你第一次嘗試使用 git 指令向倉庫提交一個更改時,你可能會收到這樣的歡迎訊息:
*** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity.
你可能沒有意識到正是這些指令在修改 ~/.gitconfig 的內容,這就是 Git 儲存全域設定選項的地方。你可以透過~/.gitconfig 檔案來做大量的事,包括定義別名、永久性開啟(或關閉)特定命令選項,以及修改Git 工作方式(例如,git diff 使用哪個diff 演算法,或預設使用什麼類型的合併策略)。你甚至可以根據倉庫的路徑有條件地包含其他設定檔!所有細節請參閱 man git-config。
在之前的技巧中,你可能會想知道 git config 指令中 --global 標誌是做什麼的。它告訴 Git 更新~/.gitconfig 中的「全域」配置。當然,有全域配置也意味著會有本地配置,顯然,如果你省略 --global標誌,git config 將改為更新倉庫特有的配置,該配置存儲在 .git/config 中。
在 .git/config 檔案中設定的選項將覆蓋 ~/.gitconfig 檔案中的所有設定。因此,例如,如果你需要為特定倉庫使用不同的電子郵件地址,則可以執行 git config user.email "also_you@example.com"。然後,該倉庫中的任何提交都會使用你單獨配置的電子郵件地址。如果你在開源專案中工作,並且希望它們顯示自己的電子郵件地址,同時仍然使用自己工作郵箱作為主 Git 配置,這非常有用。
幾乎任何你可以在 ~/.gitconfig 中設置的東西,你也可以在 .git/config 中進行設置,以使其作用於特定的倉庫。在下面的技巧中,當我提到將某些內容新增至 ~/.gitconfig 時,只需記住你也可以在特定倉庫的.git/config 中新增來設定那個選項。
別名是你可以在 ~/.gitconfig 中做的另一件事。它的工作原理就像命令列中的 shell 一樣—— 它們設定一個新的命令名稱,可以呼叫一個或多個其他命令,通常使用一組特定的選項或標誌。它們對於那些你經常使用的又長又複雜的指令來說非常有效。
你可以使用git config 命令來定義別名—— 例如,運行git config --global --add alias.st status 將使運行git st 與運行git status 做同樣的事情—— 但是我在定義別名時發現,直接編輯~/.gitconfig檔通常比較容易。
如果你選擇使用這種方法,你會發現 ~/.gitconfig 檔案是一個 INI 檔案。 INI 是一種帶有特定段落的鍵值對檔案格式。當加上一個別名時,你將改變 [alias] 段落。例如,定義上面相同的 git st 別名時,新增如下到檔案:
[alias] st = status
(如果已經有 [alias] 段落,只需將第二行新增至現有部分。)
别名不仅仅限于运行其他 Git 子命令 —— 你还可以定义运行其他 shell 命令的别名。这是一个用来处理一个反复发生的、罕见和复杂的任务的很好方式:一旦你确定了如何完成它,就可以在别名下保存该命令。例如,我有一些复刻的开源项目的仓库,并进行了一些本地修改。我想跟上项目正在进行的开发工作,并保存我本地的变化。为了实现这个目标,我需要定期将来自上游仓库的更改合并到我复刻的项目中 —— 我通过使用我称之为upstream-merge 的别名来完成。它是这样定义的:
upstream-merge = !"git fetch origin -v && git fetch upstream -v && git merge upstream/master && git push"
别名定义开头的 ! 告诉 Git 通过 shell 运行这个命令。这个例子涉及到运行一些 git 命令,但是以这种方式定义的别名可以运行任何 shell 命令。
(注意,如果你想复制我的 upstream-merge 别名,你需要确保你有一个名为 upstream 的 Git 远程仓库,指向你已经分配的上游仓库,你可以通过运行 git remote add upstream
如果你在一个有很多分支活动的项目上开发,有时可能很难掌握所有正在发生的工作以及它们之间的相关性。各种图形用户界面工具可让你获取不同分支的图片并在所谓的“提交图表”中提交。例如,以下是我使用 GitLab提交图表查看器可视化的我的一个仓库的一部分:
GitLab commit graph viewer
如果你是一个专注于命令行的用户或者发现分支切换工具让人分心,那么可以从命令行获得类似的提交视图。这就是 git log 命令的 --graph 参数出现的地方:
Repository visualized with --graph command
以下命令可视化相同仓库可达到相同效果:
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)%Creset' --abbrev-commit --date=relative
--graph 选项将图添加到日志的左侧,--abbrev-commit 缩短提交的 SHA 值,--date=relative 以相对方式表示日期,以及 --pretty 来处理所有其他自定义格式。我有个 git lg 别名用于这个功能,它是我最常用的 10 个命令之一。
有时,你越是想避开越避不开,你会发现你需要运行 git push --force 来覆盖仓库远程副本上的历史记录。你可能得到了一些反馈,需要你进行交互式变基,或者你可能已经搞砸了,并希望隐藏“罪证”。
当其他人在仓库的远程副本的同一分支上进行更改时,会发生强制推送的危险。当你强制推送已重写的历史记录时,这些提交将会丢失。这就是 git push --force-with-lease 出现的原因 -- 如果远程分支已经更新,它不会允许你强制推送,这确保你不会丢掉别人的工作。
你是否使用过 git commit -a 在一次行动中提交所有未完成的修改,但在你推送完提交后才发现 git commit -a 忽略了新添加的文件?你可以使用 git add -N (想想 “notify”) 来解决这个问题,告诉 Git 在第一次实际提交它们之前,你希望在提交中包含新增文件。
Git을 사용할 때 가장 좋은 방법은 각 커밋에 버그 수정이든 새 기능 추가든 논리적 변경 사항이 하나만 포함되도록 하는 것입니다. 그러나 작업할 때 저장소의 변경 사항이 여러 커밋을 사용하게 되는 경우가 있습니다. 각 커밋에 적절한 변경 사항만 포함되도록 어떻게 항목을 분리할 수 있나요? git add --patch가 여러분을 구하기 위해 여기에 있습니다!
이 플래그를 사용하면 git add 명령이 작업 복사본의 모든 변경 사항을 확인하고 각 변경 사항을 커밋할지, 건너뛸지, 결정을 연기할지 묻습니다(명령을 실행한 후 ?를 선택하면 다른 변경 사항을 더 자세히 볼 수 있습니다). 강력한 옵션). git add -p는 잘 구조화된 커밋을 생성하는 훌륭한 도구입니다.
git add -p와 유사하게 git checkout 명령은 --patch 또는 -p 옵션도 허용합니다. 이 옵션을 사용하면 로컬 작업 복사본에 있는 변경 사항의 각 "청크"를 표시하고 간단히 말해서 삭제할 수 있습니다. 로컬 작업 복사본을 변경 전 상태로 복원합니다.
정말 대단해요. 예를 들어, 여러 디버그 로그 문을 생성하는 버그를 추적하는 경우 버그를 수정한 후 먼저 git checkout -p를 사용하여 모든 새 디버그 로그를 제거한 다음 git add -p를 사용하여 버그 수정을 추가할 수 있습니다. 우아하고 잘 구성된 제출물을 구성하는 것보다 더 만족스러운 것은 없습니다!
일부 프로젝트에는 저장소의 모든 커밋이 작업 상태에 있어야 한다는 규칙이 있습니다. 즉, 모든 커밋에서 코드를 컴파일할 수 있어야 하거나 테스트 스위트가 실패 없이 실행되어야 합니다. 브랜치에서 작업할 때는 어렵지 않지만 어떤 이유로 rebase해야 하는 경우 실수로 도입하지 않도록 각 리베이스 커밋을 단계별로 실행해야 합니다. 휴식을 취하고 이 과정은 지루합니다.
다행히도 git rebase는 이미 -x 또는 --exec 옵션을 재정의합니다. git rebase -x
많은 Git 하위 명령은 특정 커밋의 SHA1 값, 브랜치 이름 또는 심지어 HEAD(현재 체크아웃을 나타냄)와 같은 기호 이름일 수 있는 명령이 작동하는 저장소 부분을 결정하기 위해 개정 매개변수를 허용합니다. 브랜치의 마지막 커밋) 이러한 간단한 형식 외에도 "이 시간에 대한 참조"를 나타내는 매개변수로 지정된 날짜나 시간을 추가할 수도 있습니다.
이 기능은 언젠가는 매우 유용해질 것입니다. 최신 버그를 처리하고 스스로에게 "어제 이 기능은 괜찮았는데 무엇이 변경되었나요?"라고 말할 때 커밋이 언제 변경되었는지 알아내려고 git log 출력의 전체 화면을 쳐다보는 대신 git을 실행하면 됩니다. HEAD@{yesterday}를 비교하여 어제 이후의 모든 수정 사항을 확인하세요. 이는 더 긴 기간(예: git diff HEAD@{'2개월 전'})뿐만 아니라 정확한 날짜(예: git diff HEAD@{'2010-01-01 12:00:00'})에도 작동합니다.
개정 매개변수를 사용하는 Git 하위 명령과 함께 이러한 날짜 기반 개정 매개변수를 사용할 수도 있습니다. gitrevisions 매뉴얼 페이지에 사용할 형식에 대한 자세한 내용이 나와 있습니다.
리베이스 중에 커밋을 종료하려고 시도한 후 해당 커밋에 무언가를 유지해야 한다는 사실을 발견한 적이 있습니까? 이 정보는 결코 검색할 수 없으며 재생성만 가능하다고 느낄 수도 있습니다. 그러나 로컬 작업 복사본에 커밋하면 해당 커밋이 reflog에 추가되고 계속 액세스할 수 있습니다.
git reflog를 실행하면 로컬 작업 복사본의 현재 브랜치에 대한 모든 활동 목록이 표시되고 각 커밋의 SHA1 값이 제공됩니다. 리베이스할 때 포기한 커밋을 찾으면 git checkout
아야! 내 기본 수학 능력이 Git 능력보다 열등하다는 것이 밝혀졌습니다. Git은 원래 2005년에 출시되었습니다. 즉, 올해로 12년이 아닌 13년이 됩니다. 그 실수를 만회하기 위해 우리를 13세로 만들 수 있는 13번 팁을 알려드리겠습니다.
브랜치 기반 워크플로를 사용하는 경우 장기 프로젝트를 진행하면서 각 브랜치를 병합하면서 정리하지 않으면 수많은 브랜치만 남게 됩니다. 이로 인해 원하는 가지를 찾기가 어려워지고, 가지의 숲으로 인해 찾기가 불가능해집니다. 더 나쁜 것은 활성 분기가 많은 경우 분기가 병합되었는지(안전하게 삭제할 수 있음) 또는 여전히 병합되지 않아 그대로 두어야 하는지 결정하는 것이 매우 지루할 수 있다는 것입니다. 다행스럽게도 Git이 도움이 될 수 있습니다. git Branch --merged를 실행하면 현재 브랜치에 병합된 브랜치 목록을 얻을 수 있고, git Branch --no-merged를 실행하면 어떤 브랜치가 다른 브랜치에 병합되었는지 확인할 수 있습니다. 기본적으로 이는 로컬 작업 복사본의 브랜치를 나열하지만 명령줄에 --remote 또는 -r 인수를 포함하면 원격 저장소에만 존재하는 병합된 브랜치도 나열됩니다.
중요: git Branch --merged의 출력을 사용하여 병합된 브랜치를 정리하려는 경우 출력에 현재 브랜치도 포함된다는 점에 주의해야 합니다(결국 이 현재 브랜치는 현재 브랜치에 병합됩니다). 나뭇가지!). 삭제하기 전에 해당 분기를 제외했는지 확인하세요(잊었다면 팁 12를 참조하여 reflog가 분기를 다시 가져오는 데 어떻게 도움이 되는지 알아보세요. 도움이 되기를 바랍니다...).
이 팁 중 적어도 하나를 통해 계속해서 혁신하고 새로운 기능을 추가하는 13년 된 프로젝트인 Git에 대해 새로운 것을 배울 수 있기를 바랍니다. 당신이 가장 좋아하는 Git 트릭은 무엇입니까?
以上是13個實用Git技巧的詳細內容。更多資訊請關注PHP中文網其他相關文章!