工作中最常用的Git命令

Git必知必会

这是极客时间苏玲老师的《玩转Git三剑客》笔记

工作中最常用的Git命令

添加配置

查看配置

git add . 和 git add -u区别

创建仓库

额外

git add -u 可以添加所有已经被 git 控制的文件到暂存区

以前删除文件夹只会用 「-rf」,今天学到了 「-r」,并得知它们两个区别:「-r」 有时候会提示是否确认删除。

clone时指定文件夹名字

给文件重命名的简便方法

Tag标签

显示已有标签

新建标签

创建一个含附注类型的标签非常简单,用 -a (译注:取 annotated 的首字母)指定标签名字即可

删除标签

删除本地标签:

删除remote标签 :

推送标签到github

将本地所有标签推送到remote:

分支

新建分支

切换分支

新建分支并切换到分支

删除分支

通过git log查看版本演变历史

通过图形界面工具来查看版本历史

探密.git目录

查看.git文件夹下的内容:

如下:

.git里几个常用的如下:

.git/objects/ 存放所有的 git 对象,对象哈希值前 2 位作为文件夹名称,后 38 位作为对象文件名, 可通过 git cat-file -p 命令,拼接文件夹名称+文件名查看。

commit、tree和blob三个对象之间的关系

img

【同学问题】 每次commit,git 都会将当前项目的所有文件夹及文件快照保存到objects目录,如果项目文件比较大,不断迭代,commit无数次后,objects目录中文件大小是不是会变得无限大?

【老师解答】 Git对于内容相同的文件只会存一个blob,不同的commit的区别是commit、tree和有差异的blob,多数未变更的文件对应的blob都是相同的,这么设计对于版本管理系统来说可以省很多存储空间。其次,Git还有增量存储的机制,我估计是对于差异很小的blob设计的吧。

分离头指针情况下的注意事项

detached HEAD

进一步理解HEAD和branch

怎么删除不需要的分支?

查看分支:

删除分支命令:

怎么修改最新commit的message

怎么修改老旧commit的message

接下来就是一个交互过程…

这期间会产生一个detached HEAD,然后将改好的commit指向该detached HEAD,如下图所示:

img

git rebase工作的过程中,就是用了分离头指针。rebase意味着基于新base的commit来变更部分commits。它处理的时候,把HEAD指向base的commit,此时如果该commit没有对应branch,就处于分离头指针的状态,然后重新一个一个生成新的commit,当rebase创建完最后一个commit后,结束分离头状态,Git让变完基的分支名指向HEAD。

怎样把连续的多个commit整理成1个

Git修改gitignore后生效

寻找并删除Git记录中的大文件

本文来介绍查找和重写Git记录的命令:git rev-list , git filter-branch 。生产环境请考虑使用 bfg 等效率工具。

首先通过rev-list来找到仓库记录中的大文件:

然后通过 filter-branch 来重写这些大文件涉及到的所有提交(重写历史记录):

Git仓库的存储方式

如果你熟知Git的存储方式,跳过此节。

Git仓库位于项目根目录的 .git 文件夹,其中保存了从仓库建立(git init)以来所有的代码增删。 每一个提交(Commit)相当于一个Patch应用在之前的项目上,借此一个项目可以回到任何一次提交时的文件状态。

于是在Git中删除一个文件时,Git只是记录了该删除操作,该记录作为一个Patch存储在 .git 中。 删除前的文件仍然在Git仓库中保存着。直接删除文件并提交起不到给Git仓库瘦身的效果。

在Git仓库彻底删除一个文件只有一种办法:重写(Rewrite)涉及该文件的所有提交。 幸运的是借助 git filter-branch 便可以重写历史提交,当然这也是Git中最危险的操作。 可以说比 rm -rf * 危险一万倍。

从所有提交中删除一个文件

如果清楚地记得曾提交过名为 recent-badge.psd 的文件。这是一个很大的PhotoShop文件,要把它删掉。 filter-branch 命令可以用来重写Git仓库中的提交, 利用filter-branch 的 --index-filter参数便能把它从所有Git提交中删除。

寻找大文件的ID

删掉了recent-badge.psd后我仍不满足,我要找到所有的大文件,并把它删掉。 verify-pack命令用来验证Git打包的归档文件,我们用它来找到那些大文件。 例如:

现在变得到了最大的5个文件的ID,而我需要文件名才能用filter-branch移除它。 我现在需要文件ID和文件名的映射关系。

文件名与ID映射

rev-list命令用来列出Git仓库中的提交,我们用它来列出所有提交中涉及的文件名及其ID。 该命令可以指定只显示某个引用(或分支)的上下游的提交。例如:

将会列出所有从foo和bar可到达,但从baz不可到达的提交。我们将会用到rev-list的两个参数:

现在就得到了文件名(如_posts/2013-10-12-2.md)和ID(如6cdbb293d453ced07e6a07e0aa6e580e6a5538f4 )的映射关系。

得到文件名列表

前面我们通过rev-list得到了文件名-ID的对应关系,通过verify-pack得到了最大的5个文件ID。 用后者筛选前者便能得到最大的5个文件的文件名:

先把上面输出存到large-files.txt中。还记得吗?--tree-filter参数中我们需要给出一行的文件名列表。上述列表我们需要处理一下:

现在便得到了一行的文件列表。把它存到large-files-inline.txt中。

删除所有大文件

现在得到了要删除的大文件列表large-files-inline.txt,把它传入到--tree-filter中即可:

注意这里--index-filter的参数要用双引号,因为cat large-files-inline.txt还需要Bash的解析。

至此已经干掉了那些大文件,来看看瘦身了多少吧! 注意filter-branch之后.git目录下会有大量的备份。

当然到此为止我们更改的都是本地仓库,现在把这些改变Push到远程仓库中去!

因为不是fast forward,所以需要指定--force参数。

这里的--all会将所有分支都推送到origin上。当然你也可以只推送master分支:git push origin master --force。但是!如果其它远程分支有那些大文件提交的话,仍然没有瘦身!

怎么比较暂存区和HEAD所含文件的差异?

或者

怎么比较工作区和暂存区所含文件的差异?

如何让暂存区恢复成和HEAD的一样?

如何让工作区的文件恢复为和暂存区一样?

恢复工作区用checkout,恢复暂存区用reset。

怎样取消暂存区部分文件的更改?

看看不同提交的指定文件的差异

正确删除文件的方法

开发中临时加塞了紧急任务怎么处理?

如何指定不需要Git管理的文件?

【同学提问】 如果提交commit后,想再忽略一些已经提交的文件,怎么处理。

【老师回答】 The problem is that .gitignore ignores just files that weren't tracked before (by git add). Run git reset name_of_file to unstage the file and keep it. In case you want to also remove given file from the repository (after pushing), use git rm --cached name_of_file.

把想忽略的文件添加到 .gitignore ;然后通过 git rm -- cached name_of_file 的方式删除掉git仓库里面无需跟踪的文件。

添加远程仓库

配置公私钥

1、 检查是否已存在相应的ssh key:

打开终端, 输入:

核对列出来的ssh key是否有已存在的,假如你没有看到列出的公私钥对,或是不想再用之前的公私钥对,你可以选择下面的步骤生成新的公私钥对.

2、 生成新的ssh key,并添加至ssh-agent:

2.1 打开终端, 使用ssh key生成命令:

注意 :后面的邮箱对应相应账号的邮箱,假如是github的账号,且注册账号的邮箱为xxx@gmail.com,则命令行为:

2.2 接下来会提示你保存的ssh key的名称以及路径。

默认路径是/home/you/.ssh/id_rsa(you为用户个人目录)即~/.ssh/id_rsa。这一步很重要,如果你使用默认的,且下一个账号也是使用默认的路径和文件名,那么之前的ssh key就会被后来生成的ssh key重写,从而导致之前的账号不可用。因此,正确的做法是给它命名,最后以应用名进行命名,因为更容易区分。以下是我个人配的:

2.3 接下来会提示设置ssh安全密码。

这一步可以使用默认的(即不设置密码),直接按回车即可。

这里会生成xxx_rsa和xxx_rsa.pub两个文件,xxx_rsa是生成的ssh key的私钥名,xxx_rsa.pub是生成的ssh key的公钥名,私钥要放在本地,公钥要放在服务器或github的Settings->SSHand GPG keys->New SSH key上。

img

2.4 ssh key生成后,接下来需要为ssh key添加代理。

这是为了让请求自动对应相应的账号。网上很多文章写到需要另外配置config文件,经本人亲测,其实是不需要的,在生成了ssh key后,通过为生成的ssh key添加代理即可,为ssh key添加代理命令:ssh-add ~/.ssh/xxx_rsa, xxx_rsa是你生成的ssh key的私钥名,我的设置为:

这里有可能会提示以下错误:

img

解决方法:

需要ssh-agent启动bash,或者说把bash挂到ssh-agent下面

3、 将生成的xxx_rsa.pub公钥内容添加到GitLab的SSH keys页面上。

img

4、 连接测试

接下来我们测试是否配置成功,打开终端,输入:

img

怎么快速淘到感兴趣的开源项目

UI界面高级搜索: https://github.com/search/advanced

命令高级搜索

上述命令的意思是搜索reademe中包含git、最好、学习、资料”且star大于1000的,用C语言编写的仓库。