由total Developers提供的Git最佳实践和技巧

Share

这个资源包含了由total网络成员提供的Git最佳实践和Git技巧的集合.

这个资源包含了由total网络成员提供的Git最佳实践和Git技巧的集合. As such, 本页将定期更新,以包含更多信息,并涵盖新兴的Git技术. 这是一个社区驱动的项目, 所以我们也鼓励你们做出贡献, 我们期待着你们的反馈.

Git不仅是一个版本控制系统,也是一个协作和发布管理系统. 使用和理解Git是任何开发团队的基本技能. 同时, Git is comprehensive and complex; even simple tasks may need commands that can only be executed from the command line (terminal) without any GUI help. 这就是为什么我们想要我们的顶部 Git开发人员和工程师 分享他们的知识,提供他们最好的建议.

如何检查未知命令将修改哪些文件

假设您被分配到一个项目,该项目使用一个小的遗留命令来操作一些文件. 不幸的是,这个命令没有文档记录. So, 您如何确定该命令访问哪些文件以及它对这些文件进行了哪些更改?

找到这一点的最简单方法之一是使用Git. 首先,将整个项目复制到安全的测试环境中,并使用 git init 命令初始化一个新的Git存储库. Next, 执行所讨论的遗留命令和, 结束后, 检查发生了哪些更改 git diff command. 删除存储库时,只需运行 rm -rf .git command.

Contributors

胡安·尤金尼奥·阿巴迪

全栈开发者(Ingenea SRL)

热爱开源软件和学习新技术的专业C/ c++ /Web开发人员.

从Toptal获取最新的开发人员更新.

订阅意味着同意我们的 privacy policy

是否可以同时使用多个GitHub, GitLab和Bitbucket帐户?

当你的客户要求你使用他们的电子邮件地址创建一个应该与你的私人账户完全分开的GitHub账户时,你应该怎么做? Or, 假设您有一个客户,没有太多的可用时间(一如既往), 他们会给你他们的GitHub账户凭证. 或者,您可能需要访问一些私有存储库,您无法更改权限并邀请更多用户. 或者甚至你的客户用不同于你预期的电子邮件发送了邀请, 然后客户去度假了.

在所有这些情况下,您需要从同一台开发机器管理多个GitHub帐户. 如果您正在使用SSH密钥, 这将会有一个问题,因为你的钥匙已经连接到你的个人账户. 可以使用以下命令克隆Git存储库 http URL,并在每次需要部署时键入密码, 但这可能是一个问题,因为你需要记住所有的密码, 记录下那些改变了的.

但是,有一种方法可以使用多个SSH密钥继续处理多个帐户.

首先,您需要使用以下命令生成密钥:

Ssh-keygen -f ~/.ssh / id_rsa_my_company_account
为空密码短语按enter键

使用如下命令查找私钥和公钥:

ls ~/.ssh / id_rsa_my_company_account *

然后,您需要将公钥添加到GitHub/GitLab/Bitbucket设置中. 可以复制粘贴如下命令的输出信息:

cat ~/.ssh / id_rsa_my_company_account.pub

有一个非常有用的命令 ssh-add 来帮助您管理SSH密钥. 列表中当前保存的所有SSH密钥 X-session,或登录会话 ssh-agent 已启动,可以执行如下命令:

ssh-add - l#列出所有当前密钥

您可以通过简单地调用它来启动一个新的代理:

ssh-agent bash -c 'ssh-add -L' #代理没有身份.

因此,您可以使用以下两个命令(ssh-add and ssh-agent)将密钥设置为另一个帐户.

Ssh-agent bash -c 'ssh-add ~/.ssh / id_rsa_my_company_account; git clone git@github.com:公司/回购.git'

对某些存储库使用这些特定密钥的另一种方法是配置SSH. 让我们命名这个存储库 my_company_account_github.com (不用担心,它会被翻译成 github.com domain). 创建一个文件 ~/.ssh/config 内容如下:

主机my_company_account_github.com
  主机名github.com
  IdentityFile ~ /.ssh / id_rsa_my_company_account

当您想下载存储库时,只需使用新的假存储库域名.

Git克隆git@my_company_account_github.com:公司/回购.git
# this将使用~/.ssh / id_rsa_my_company_account键

如果您决定更改已克隆的repo所使用的键,则可以进行编辑 .git/config or use Git remote set-url origin git@my_company_account_github.com:公司/回购.git.

要查看哪个用户名(-T)和哪个键(-v) SSH正在使用:

ssh -T git@my_company_account_github.com
SSH -v git@my_company_account_github.com

如果需要,可以使用密码(passsphrase)生成SSH密钥. 我不建议这样做,因为它会要求您每次使用的关键密码短语 git command.

请注意,对于某些部署系统, like Heroku, 在推送到他们的存储库之前,您还需要登录. Heroku把钥匙放进去 ~/.netrc,在键入时创建 heroku login. 记住,一旦设置好了,它就永远存在了. 记住你需要用 heroku login 使用连接到SSH密钥的相同帐户使其工作.

Contributors

Dusan Orlovic

自由Git开发人员

Serbia

Dusan Orlovic(杜克大学)是一位具有Ruby on Rails经验的工程师. 他认为,网络和移动应用程序需要通过共享数据与其他应用程序连接起来, visitors, 以及为了在市场上生存的结果. 这就是Duke编写连接各种服务的现代的、经过良好测试的、可维护的代码的原因. 开源软件使他成为一个更好的程序员,并为他提供了实现网络想法所需的工具.

Show More

如何创建非常短的快捷方式?

添加别名 .gitconfig 的优点是保留了Git的自动完成功能,但它也有缺点. 这些命令至少有5个字符长,比如 git c, 而且5个字符对于你一天要打几十次的命令来说还是太长了. 如果采用替代路径并创建bash别名,如 gc,您将失去自动完成功能. 幸运的是,有一种方法可以使用Bash别名实现自动完成. Bash使用命令 __git_complete 你可以用它来注册你的化名. 将以下内容添加到您的RC脚本之一:

别名gc= ' git checkout '
. /usr/share/bash-completion /完成/ git
__git_complete git_checkout

第二行代码将Git自动完成函数加载到Bash中, without it, 它们只有在您尝试自动完成第一个Git命令后才会被加载. 查看Git命令列表 __git_complete accepts, type _git_ 触发自动补全. 这已被证实可以与Git 2一起工作.7.4 and Bash 4.3.12.

Contributors

Dmitry Lashkov

自由Git开发人员

Russia

Dmitry是一名拥有7年以上经验的软件工程师. 他使用过现有的产品, 从零开始构建复杂的, 并且有专注的能力, dive in, 并且完全理解他正在解决的问题. 他喜欢自动化测试, 审核过的拉取请求, 以及敏捷方法,因为它们允许开发人员构建高质量的产品并实现专业发展. Ruby和Ember是他选择的技术.

Show More

什么时候是100%安全的?

重基的主要目标是摆脱冗余的合并提交,并利用不需要提交的快进合并. 重基合并和快进合并一起工作,在Git是分布式版本控制系统的情况下非常有用.

想象一下这样一个情况:您在特性分支上做了一些工作,并试图将其推送到远程存储库中, 但是你的要求被拒绝了, 因为你的同事刚刚在你之前推动了一些改变. 如果你现在知道 git pull,然后在底层执行Git git fetch && Git merge 来源/新功能. 而不是通常的快速合并,只是简单地向分支添加新的提交, in this case, 它将另外创建一个实际的合并提交,因为您的本地 new-feature and remote new-feature 分支已改道.

通过以下操作可以很容易地避免这种冗余的合并提交 git fetch and Git rebase 来源/新功能. Rebase将重写本地分支的历史记录,使其看起来像您比您的同事晚完成了所有提交.

重基未合并的本地分支 new-feature 使用各自的远程跟踪分支 来源/新功能 是否总是100%安全,因为您只重写了本地提交历史中未推送的部分. 没有人看到您的新提交,您可以对它们做任何您想做的事情. 这就是分布式版本控制系统的美妙之处.

唯一的不便之处在于,在基地变更冲突的情况下, Git在local的冲突标记中翻转角色 new-feature 与remote-tracking 来源/新功能 并调用远程HEAD,而在合并冲突的情况下,它将调用本地HEAD.

Contributors

Dmitry Lashkov

自由Git开发人员

Russia

Dmitry是一名拥有7年以上经验的软件工程师. 他使用过现有的产品, 从零开始构建复杂的, 并且有专注的能力, dive in, 并且完全理解他正在解决的问题. 他喜欢自动化测试, 审核过的拉取请求, 以及敏捷方法,因为它们允许开发人员构建高质量的产品并实现专业发展. Ruby和Ember是他选择的技术.

Show More

为什么Git Stash是危险的?

您是否曾经将更改隐藏在当前的特性分支上, 切换到主分支进行热修复, 然后回到特征分支? If so, 您可能会无意中将一些新特性文件泄漏到主分支中.

考虑以下场景:在您的特性分支上,您创建了一个新文件 new-cool-feature.js. 突然,需要紧急修复,所以你做了 git stash. 你签出主分支,创建了一个文件 controller.js, did git add --all && git commit -m ' Fix '推了推树枝. Unexpectedly, new-cool-feature.js 最终会被推到你的主分支吗. 这是因为 git stash 就像 git commit -a这意味着它会忽略尚未被Git跟踪的新文件.

有一个开关 -u which tells git stash 也用来存放无法追踪的文件,但我建议尽量避免 git stash 在涉及分支交换的情况下. 在切换到通常的分支之前,将临时在制品提交简单地放在分支的顶部要容易得多 git add --all && git commit -m ' WIP ',然后当你换回来的时候,再做 git reset HEAD^.

这有两个好处:

  1. 不需要记住额外的存储命令,如列出所有存储,或存储未跟踪的文件. 它是常用的Git提交例程 git add, git commit, and git log.
  2. 如果您在几个分支上有在制品提交, 当你回来的时候,没有必要去挑选你需要的那个, 就像藏毒品一样. 它总是一样的 git reset HEAD^.

不过,我得说有一种情况 git stash 使用安全方便吗, 什么时候您想看看未提交的代码如何改变软件的行为. 在这种情况下,您可以快速做到 git stash,看看它在你的新改变之前是如何工作的,然后 git stash pop to go back. 不会意外地隐藏一些文件, in this case, 几乎没有任何后果, 因为无论如何,您将在同一分支上卸载. 也不存在从列表中选择正确藏匿点的问题.

Contributors

Dmitry Lashkov

自由Git开发人员

Russia

Dmitry是一名拥有7年以上经验的软件工程师. 他使用过现有的产品, 从零开始构建复杂的, 并且有专注的能力, dive in, 并且完全理解他正在解决的问题. 他喜欢自动化测试, 审核过的拉取请求, 以及敏捷方法,因为它们允许开发人员构建高质量的产品并实现专业发展. Ruby和Ember是他选择的技术.

Show More

Git快捷方式可以让你更有效率. Here's How.

有一些有趣的Git快捷方式可以添加到本地 .gitconfig file. 通过添加这些快捷键, 您应该能够通过输入两个或三个字符来运行Git命令, 并且可以更快地执行常见的Git操作,而不是键入10个字符或更多的长命令.

我们需要做的第一件事就是看看我们的用户 .gitconfig file. 对于Linux和Mac,它位于主目录: /home//.gitconfig for Linux, /Users//.gitconfig 对于Mac来说,或者简单地说 ~/.gitconfig for both. 对于Windows,它位于 C:\Users\\.gitconfig. If the .gitconfig 文件不存在,我们需要创建一个空文件.

所有东西都加到 .gitconfig 文件变得全局可用,并将在我们所有的Git存储库中工作. 创建新的快捷方式, 我们需要在文件中编辑(如果不存在,则创建)别名部分.

例如,我们可以缩写the git add 命令到。 git a 通过在alias部分下添加以下行:

[alias]
    a = add

变得更有效率, 下面是我们建议的最常用的Git命令列表和它们的别名:

[alias]
    a = add
    Cka = add——patch # stage逐个块提交
    Ci = commit - m# commit with message
    Ca = commit -am # commit all with message
  
    co = checkout         
    Nb = checkout -b # Nb代表新分支               

    Cp =樱桃-x

    D = diff # diff未分级更改
    Dc = diff——cached # diff分级更改
    last = diff HEAD^ # diff最后提交的更改

    pl = pull
    ps = push            

    Rc = rebase—继续
    Rs = rebase—跳过

    ss = stash
    Sl =藏匿清单
    Sa =隐藏应用
    Sd =藏匿物品掉落

现在如何使用快捷键? 让我们选择一个长命令作为示例. 我们正在进行一次重新base,在修复了文件中的冲突之后,我们需要告诉Git继续重新base. 如果没有快捷键,我们将输入:

$ git rebase——继续

使用快捷方式,我们只需要输入:

$ git rc

其他一些有趣的快捷命令,我们可以添加到 ~/.gitconfig 从索引中删除文件的命令是吗, 将我们的状态倒回到上次提交之前, 并删除所有已经拉到master的分支:

[alias]
    # ...
    unstage = reset HEAD
    uncommit = reset -soft HEAD^
    
    删除合并的分支= "!F () {git checkout——安静的主人 && git branch --merged | grep --invert-match '\\*' | xargs -n 1 git branch --delete; git checkout --quiet @{-1}; }; f"

我们现在分别这样做:

$ git unstage
$ git uncommit
$ git delete-merged-branches

最后一个很长,但是你可以把它映射成 dmb 或者按TAB键使用shell自动补全.

使用Git快捷方式, or aliases, 从命令行使用Git是提高生产力的好方法吗. 跟踪您使用的命令并添加简短的别名是值得的.

Contributors

Ivan Neto

自由Git开发人员

Brazil

Ivan是一名工程师,在软件和网络开发方面有八年的经验. 主要专注于网络, 他解决了成长系统中出现的代码优化问题, 以及迁移的生产应用程序和服务的零停机时间. 虽然他的大部分经验都是在后台, 他还可以处理前端, databases, networking, 和基础设施.

Show More

在Git仓库中,我们如何列出在特定日期之后被更改的文件?

Git有一些强大的子命令. 用这些, 结合一点Bash脚本编写, 您可以生成存储库中在特定日期之后更改的所有文件的列表.

for h in `Git日志——pretty=format:"%h"——since="2015-05-26"`; do
	Git show——pretty="format:"——name-only $h
完成| sort | unique

这个命令乍一看似乎势不可挡, 但为了更容易理解它是如何工作的,我们可以把它分解一下:

for h in {list of commits since given date}; do
    {列出提交h中的文件}
完成|{删除所有重复项}

我们首先循环遍历自指定日期以来所做的所有提交. 生成此列表的命令是 Git日志——pretty=format:"%h"——since="2015-05-26". 这个特殊的命令列出了自那以后的所有提交 2015-05-26. 接下来,在每次迭代中,我们将列出在该特定提交中所更改的所有文件 Git show——pretty="format:"——name-only $h, where $h 是当前迭代的提交哈希吗. 由于这个循环产生一个可能出现重复的文件列表,因此我们将输出传递给它 sort and uniq. sort 对整个文件名列表进行排序,并且 uniq 移除所有相邻的重复项.

相同命令的另一个更短的版本:

Git日志——since=2015-05-26——pretty=format:%h | xargs Git show——pretty=format:——name-only | sort -u | grep -v ^$

Contributors

克莱伯·维吉里奥·科雷亚

自由Git开发人员

Brazil

Kleber是一名软件开发人员,在IT领域有十年的专业工作经验. 他喜欢在广泛的话题上分享和获取知识, including Unix, 敏捷软件开发, 函数式和面向对象语言, 设计模式, RESTful架构, 分布式应用程序, 云计算.

Show More

Alexey Shein

自由Git开发人员

Germany

Alexey是一位才华横溢的软件工程师,拥有超过8年的web开发经验,包括Ruby on Rails, PHP, and JavaScript. 他喜欢解决技术难题和学习新技术. 他是一个很好的导师,喜欢帮助队友.

Show More

当力推是唯一的方法

可以重写远程分支的历史 git push origin HEAD -force但99%的时候,这是一件危险的事情.

First of all, 这是因为其他人的取(拉)将被破坏,他们也将不得不强制取(拉). 然后,除非你用a ——force-with-lease,而不是传统的 --force 您可能会在拉出提交后意外删除其他人推送的有用提交.

那么为什么 --force 开关甚至存在? 当您需要永久地从历史中删除某些提交时,它适用于1%的情况. 一个例子是,当您想要重用某些实验性分支的名称并重新开始丢弃所有的hackish提交时. 另一种情况可能是,您不小心推送了一些敏感信息,需要删除提交.

Contributors

Dmitry Lashkov

自由Git开发人员

Russia

Dmitry是一名拥有7年以上经验的软件工程师. 他使用过现有的产品, 从零开始构建复杂的, 并且有专注的能力, dive in, 并且完全理解他正在解决的问题. 他喜欢自动化测试, 审核过的拉取请求, 以及敏捷方法,因为它们允许开发人员构建高质量的产品并实现专业发展. Ruby和Ember是他选择的技术.

Show More

如何在第一次推送时自动跟踪分支?

你是否经常发现自己在推一个分支,并得到以下错误信息:

2.3.0 in ~/.test $ git push上的Dotfiles
fatal:当前分支测试没有上行分支.
推当前支路,将远端设为上游,使用

    Git push——设置上游原点测试

哦,对了,我忘了用 --set-upstream (或它的缩写) -u) flag. Again. 这太令人沮丧了,我们能不能让它自动化? The fact is, 在90%的情况下,您希望将当前分支推送到具有相同名称的原点. 别再害怕了,我们有解决办法.

把这个放进你的 .bashrc (or .zshrc 如果您是Zsh用户):

git_branch() {
  git symbolic-ref --short HEAD 2>/dev/null
}

has_tracking_branch () {
 git rev-parse --abbrev-ref @{u} > /dev/null 2>&1
}

别名gp='git push $(has_tracking_branch || echo "-u origin $(git_branch)")'

这段代码设置很方便 gp 别名,设置在第一次push时跟踪分支,并在后续调用时返回到通常的Git push:

2.3.0 in ~/.测试$ gp上的Dotfiles
计数对象:3,完成.
增量压缩使用多达8个线程.
压缩对象:100%(3/3),完成.
写入对象:100%(3/3),290字节| 0字节/秒,完成.
总共3(增量2),重用0(增量0)
To git@github.com: conf / ..git
 * [new branch]      test -> test
分支测试设置,通过重基从原点跟踪远程分支测试.

这正是我们需要的.

Contributors

Alexey Shein

自由Git开发人员

Germany

Alexey是一位才华横溢的软件工程师,拥有超过8年的web开发经验,包括Ruby on Rails, PHP, and JavaScript. 他喜欢解决技术难题和学习新技术. 他是一个很好的导师,喜欢帮助队友.

Show More

Submit a tip

提交的问题和答案将被审查和编辑, 并可能会或可能不会选择张贴, 由Toptal全权决定, LLC.

*所有字段均为必填项

Toptal连接 Top 3% 世界各地的自由职业人才.

加入Toptal社区.