首頁  >  文章  >  系統教程  >  13個實用Git技巧

13個實用Git技巧

PHPz
PHPz原創
2024-07-21 20:21:41773瀏覽

13個實用Git技巧

為了紀念 Git 的 13 歲生日,這裡有 13 個技巧和訣竅來讓你的 Git 經驗更加有用和強大。從你可能忽略的一些基本知識開始,並擴展到一些真正的高級用戶技巧!

1、 你的 ~/.gitconfig 檔案

當你第一次嘗試使用 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。

2、 你倉庫中的 .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 中新增來設定那個選項。

3、 別名

別名是你可以在 ~/.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] 段落,只需將第二行新增至現有部分。)

4、 shell 指令中的別名

别名不仅仅限于运行其他 Git 子命令 —— 你还可以定义运行其他 shell 命令的别名。这是一个用来处理一个反复发生的、罕见和复杂的任务的很好方式:一旦你确定了如何完成它,就可以在别名下保存该命令。例如,我有一些复刻fork的开源项目的仓库,并进行了一些本地修改。我想跟上项目正在进行的开发工作,并保存我本地的变化。为了实现这个目标,我需要定期将来自上游仓库的更改合并到我复刻的项目中 —— 我通过使用我称之为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 来添加一个。)

5、 可视化提交图

如果你在一个有很多分支活动的项目上开发,有时可能很难掌握所有正在发生的工作以及它们之间的相关性。各种图形用户界面工具可让你获取不同分支的图片并在所谓的“提交图表”中提交。例如,以下是我使用 GitLab提交图表查看器可视化的我的一个仓库的一部分:

13個實用Git技巧

GitLab commit graph viewer

如果你是一个专注于命令行的用户或者发现分支切换工具让人分心,那么可以从命令行获得类似的提交视图。这就是 git log 命令的 --graph 参数出现的地方:

13個實用Git技巧

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 个命令之一。

6、 更优雅的强制推送

有时,你越是想避开越避不开,你会发现你需要运行 git push --force 来覆盖仓库远程副本上的历史记录。你可能得到了一些反馈,需要你进行交互式变基rebase,或者你可能已经搞砸了,并希望隐藏“罪证”。

当其他人在仓库的远程副本的同一分支上进行更改时,会发生强制推送的危险。当你强制推送已重写的历史记录时,这些提交将会丢失。这就是 git push --force-with-lease 出现的原因 -- 如果远程分支已经更新,它不会允许你强制推送,这确保你不会丢掉别人的工作。

7、 git add -N

你是否使用过 git commit -a 在一次行动中提交所有未完成的修改,但在你推送完提交后才发现 git commit -a 忽略了新添加的文件?你可以使用 git add -N (想想 “notify”) 来解决这个问题,告诉 Git 在第一次实际提交它们之前,你希望在提交中包含新增文件。

8、 git add -p

Git을 사용할 때 가장 좋은 방법은 각 커밋에 버그 수정이든 새 기능 추가든 논리적 변경 사항이 하나만 포함되도록 하는 것입니다. 그러나 작업할 때 저장소의 변경 사항이 여러 커밋을 사용하게 되는 경우가 있습니다. 각 커밋에 적절한 변경 사항만 포함되도록 어떻게 항목을 분리할 수 있나요? git add --patch가 여러분을 구하기 위해 여기에 있습니다!

이 플래그를 사용하면 git add 명령이 작업 복사본의 모든 변경 사항을 확인하고 각 변경 사항을 커밋할지, 건너뛸지, 결정을 연기할지 묻습니다(명령을 실행한 후 ?를 선택하면 다른 변경 사항을 더 자세히 볼 수 있습니다). 강력한 옵션). git add -p는 잘 구조화된 커밋을 생성하는 훌륭한 도구입니다.

9.git 체크아웃 -p

git add -p와 유사하게 git checkout 명령은 --patch 또는 -p 옵션도 허용합니다. 이 옵션을 사용하면 로컬 작업 복사본에 있는 변경 사항의 각 "청크"를 표시하고 간단히 말해서 삭제할 수 있습니다. 로컬 작업 복사본을 변경 전 상태로 복원합니다.

정말 대단해요. 예를 들어, 여러 디버그 로그 문을 생성하는 버그를 추적하는 경우 버그를 수정한 후 먼저 git checkout -p를 사용하여 모든 새 디버그 로그를 제거한 다음 git add -p를 사용하여 버그 수정을 추가할 수 있습니다. 우아하고 잘 구성된 제출물을 구성하는 것보다 더 만족스러운 것은 없습니다!

10. 리베이스할 때 명령 실행

일부 프로젝트에는 저장소의 모든 커밋이 작업 상태에 있어야 한다는 규칙이 있습니다. 즉, 모든 커밋에서 코드를 컴파일할 수 있어야 하거나 테스트 스위트가 실패 없이 실행되어야 합니다. 브랜치에서 작업할 때는 어렵지 않지만 어떤 이유로 rebase해야 하는 경우 실수로 도입하지 않도록 각 리베이스 커밋을 단계별로 실행해야 합니다. 휴식을 취하고 이 과정은 지루합니다.

다행히도 git rebase는 이미 -x 또는 --exec 옵션을 재정의합니다. git rebase -x 는 리베이스에 각 커밋이 적용된 후 이 명령을 실행합니다. 예를 들어 npm run 테스트를 사용하여 테스트 스위트를 실행하는 프로젝트가 있는 경우 git rebase -x npm run 테스트는 리베이스 중 모든 커밋 후에 테스트 스위트를 실행합니다. 이를 통해 테스트 스위트가 리베이스된 커밋에서 실패하는지 확인할 수 있으므로 테스트 스위트가 각 커밋에서 여전히 통과하는지 확인할 수 있습니다.

11. 시간 기준 개정 인용

많은 Git 하위 명령은 특정 커밋의 SHA1 값, 브랜치 이름 또는 심지어 HEAD(현재 체크아웃을 나타냄)와 같은 기호 이름일 수 있는 명령이 작동하는 저장소 부분을 결정하기 위해 개정 매개변수를 허용합니다. 브랜치의 마지막 커밋) 이러한 간단한 형식 외에도 "이 시간에 대한 참조"를 나타내는 매개변수로 지정된 날짜나 시간을 추가할 수도 있습니다.

이 기능은 언젠가는 매우 유용해질 것입니다. 최신 버그를 처리하고 스스로에게 "어제 이 기능은 괜찮았는데 무엇이 변경되었나요?"라고 말할 때 커밋이 언제 변경되었는지 알아내려고 git log 출력의 전체 화면을 쳐다보는 대신 git을 실행하면 됩니다. HEAD@{yesterday}를 비교하여 어제 이후의 모든 수정 사항을 확인하세요. 이는 더 긴 기간(예: git diff HEAD@{'2개월 전'})뿐만 아니라 정확한 날짜(예: git diff HEAD@{'2010-01-01 12:00:00'})에도 작동합니다.

개정 매개변수를 사용하는 Git 하위 명령과 함께 이러한 날짜 기반 개정 매개변수를 사용할 수도 있습니다. gitrevisions 매뉴얼 페이지에 사용할 형식에 대한 자세한 내용이 나와 있습니다.

12.전지적 리프로그

리베이스 중에 커밋을 종료하려고 시도한 후 해당 커밋에 무언가를 유지해야 한다는 사실을 발견한 적이 있습니까? 이 정보는 결코 검색할 수 없으며 재생성만 가능하다고 느낄 수도 있습니다. 그러나 로컬 작업 복사본에 커밋하면 해당 커밋이 reflog에 추가되고 계속 액세스할 수 있습니다.

git reflog를 실행하면 로컬 작업 복사본의 현재 브랜치에 대한 모든 활동 목록이 표시되고 각 커밋의 SHA1 값이 제공됩니다. 리베이스할 때 포기한 커밋을 찾으면 git checkout 을 실행하여 해당 커밋으로 이동하고 필요한 정보를 복사한 다음 git checkout HEAD를 실행하여 브랜치의 가장 최근 커밋으로 돌아갈 수 있습니다.

13. 스스로 청소하세요

아야! 내 기본 수학 능력이 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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn