为了纪念 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 在第一次实际提交它们之前,你希望在提交中包含新增文件。
Une bonne pratique lors de l'utilisation de Git est de s'assurer que chaque commit ne contient qu'un seul changement logique - qu'il s'agisse de corriger un bug ou d'ajouter de nouvelles fonctionnalités. Cependant, parfois, lorsque vous travaillez, les modifications apportées à votre référentiel doivent finir par utiliser plusieurs validations. Comment pouvez-vous réussir à séparer les choses pour que chaque commit ne contienne que les modifications appropriées ? git add --patch est là pour vous sauver !
Cet indicateur amènera la commande git add à examiner toutes les modifications dans votre copie de travail et à demander chaque modification si vous souhaitez la valider, l'ignorer ou différer la décision (vous pouvez sélectionner ? après avoir exécuté la commande pour en voir d'autres). options puissantes). git add -p est un excellent outil pour produire des commits bien structurés.
Semblable à git add -p, la commande git checkout accepte également l'option --patch ou -p, ce qui lui permettra d'afficher chaque "morceau" de modifications dans la copie de travail locale et de lui permettre d'être ignoré - en termes simples Restaurez la copie de travail locale dans son état avant les modifications.
C'est vraiment génial. Par exemple, lorsque vous suivez un bogue qui introduit un ensemble d'instructions de journal de débogage, après avoir corrigé le bogue, vous pouvez d'abord utiliser git checkout -p pour supprimer tous les nouveaux journaux de débogage, puis git add -p pour ajouter le correctif de bogue. Il n’y a rien de plus satisfaisant que de préparer une soumission élégante et bien structurée !
Certains projets ont pour règle que chaque validation dans le référentiel doit être en état de fonctionnement - c'est-à-dire qu'à chaque validation, le code doit pouvoir être compilé ou la suite de tests doit être exécutée sans échec. Ce n'est pas difficile lorsque vous travaillez sur une branche, mais si vous avez besoin de rebase pour une raison quelconque, vous devrez alors parcourir chaque commit rebasé pour vous assurer de ne pas introduire accidentellement une pause , et ce processus est fastidieux.
Heureusement, git rebase remplace déjà l'option -x ou --exec. git rebase -x
De nombreuses sous-commandes Git acceptent un paramètre de révision pour déterminer sur quelle partie du référentiel la commande agit, qui peut être la valeur SHA1 d'un commit spécifique, le nom d'une branche ou même un nom symbolique tel que HEAD (représentant l'extraction actuelle branche), en plus de ces formulaires simples, vous pouvez également ajouter une date ou une heure spécifiée en tant que paramètre, indiquant "une référence à cette heure".
Cette fonctionnalité deviendra très utile à un moment donné. Lorsque vous traitez le dernier bug et que vous vous dites : « Cette fonction fonctionnait bien hier, qu'est-ce qui a été modifié ? » Au lieu de regarder le plein écran de la sortie du journal git en essayant de déterminer quand le commit a été modifié, vous lancez simplement git. diff HEAD@{hier} pour voir toutes les modifications depuis hier. Cela fonctionne également pour des périodes plus longues (par exemple git diff HEAD@{'2 mois il y a'}), ainsi que pour une date exacte (par exemple git diff HEAD@{'2010-01-01 12:00:00'}) .
Vous pouvez également utiliser ces paramètres de révision basés sur la date avec n'importe quelle sous-commande Git qui utilise des paramètres de révision. Il y a des détails sur le format exact à utiliser dans la page de manuel gitrevisions.
Avez-vous déjà essayé de supprimer un commit lors d'un rebase, puis constaté que vous deviez conserver quelque chose dans ce commit ? Vous pourriez avoir l’impression que ces informations ne pourront jamais être récupérées et qu’elles ne pourront être que recréées. Mais si vous validez dans votre copie de travail locale, le commit sera ajouté au reflog et vous pourrez toujours y accéder.
L'exécution de git reflog affichera une liste de toutes les activités de la branche actuelle dans votre copie de travail locale et vous donnera la valeur SHA1 de chaque commit. Une fois que vous avez trouvé le commit que vous avez abandonné lors du rebasage, vous pouvez exécuter git checkout
Aïe ! Il s'avère que mes compétences de base en mathématiques sont inférieures à mes compétences Git. Git a été initialement publié en 2005, ce qui signifie qu'il aura 13 ans cette année au lieu de 12. Pour rattraper cette erreur, voici l’astuce numéro 13 qui peut nous transformer en treize.
Si vous utilisez un flux de travail basé sur les branches, lorsque vous travaillez sur un projet à long terme, à moins que vous ne nettoyiez chaque branche au fur et à mesure de sa fusion, vous vous retrouverez avec un tas de branches. Cela rend difficile la recherche de la branche souhaitée, et la forêt de branches rend impossible sa recherche. Pire encore, si vous avez un grand nombre de branches actives, déterminer si une branche est fusionnée (peut être supprimée en toute sécurité) ou n'est toujours pas fusionnée et doit être laissée seule peut être très fastidieux. Heureusement, Git peut vous aider : exécutez simplement git branch --merged pour obtenir une liste des branches qui ont été fusionnées dans votre branche actuelle, ou git branch --no-merged pour savoir quelles branches ont été fusionnées dans d'autres branches. Par défaut, cela listera les branches dans votre copie de travail locale, mais si vous incluez l'argument --remote ou -r sur la ligne de commande, cela listera également les branches fusionnées qui n'existent que dans le référentiel distant.
Important : Si vous prévoyez d'utiliser la sortie de git branch --merged pour nettoyer les branches qui ont été fusionnées, vous devez faire attention à ce que sa sortie inclut également la branche actuelle (après tout, cette branche actuelle est fusionnée dans la branche actuelle bifurquer!). Assurez-vous d'exclure la branche avant toute destruction (si vous oubliez, consultez l'astuce 12 pour savoir comment reflog peut vous aider à récupérer la branche, j'espère que cela vous aidera...).
J'espère qu'au moins un de ces conseils vous a appris quelque chose de nouveau sur Git, un projet vieux de 13 ans qui continue d'innover et d'ajouter de nouvelles fonctionnalités. Quelle est votre astuce Git préférée ?
Atas ialah kandungan terperinci 13 Petua Git Praktikal. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!