Git学习入门(2)- 基本命令操作总结

时间:2021-04-14 00:59:28

1 创建 git仓库

1.1 从现有工作目录中初始化新仓库

需要到你需要用git管理的项目中输入以下命令:

git init

便会创建一个空的git项目,并且当前目录下会出现一个名为 .git 的目录, Git 需要的数据和资源都存放在这个目录中,不过我们目前只是初始化所有的文件与目录

  1. 告诉 git在这个目录中有几个文件需要版本控制。我使用了几个cpp的文件
git add *.cpp

还可以:

git add README
git commit -m 'initial project version'

你已经得到了一个实际维护着若干文件的 Git 仓库。

1.2 从现有仓库克隆

克隆某个开源项目的git仓库,可以使用 git clone 命令

例如克隆一份Ruby语言的 Git 代码仓库 ticgit可以使用下面的命令

git clone git@github.com:schacon/ticgit.git

这表示在当前文件夹下新建一个ticgit,其中包含一个 .git 的文件夹,用于保存下载下来的所有版本记录,然后从中取出最新版本的文件拷贝。

修改克隆的名字

git clone git@github.com:schacon/ticgit.git myticgit

结果如下:



Git学习入门(2)- 基本命令操作总结


在克隆的时候,我们可以选择不同的数据传输协议,在我们的例子中选择的是 ssh传输协议,你还可以有https://开头或者user@server:/path.git传输协议



Git学习入门(2)- 基本命令操作总结


2. 记录仓库更新

当我们创建了git存储库后,我们便可以在工作目录对这写文件进行更新。

在工作目录中的文件无非有两种状态:

  1. 已跟踪:已跟踪的文件是指本来就被纳入版本控制管理的文件,在上次快照中有它们的记录,工作一段时间后,它们的状态可能是未更新,已修改或者已放入暂存区。在克隆获取库后,工作目录的所有文件都是已跟踪的。
  2. 未跟踪:其他所有的文件都是未跟踪的,即他们既没有快照,也没有放入暂存区。在修改后 git才会把他们表示为已修改的,然后放到暂存区准备提交更新。

2.1 查看跟踪状态

输入下面的命令来查看当前工作目录的文件处于什么状态

git status

出现的情况:

  1. 当前工作目录很干净,所有已跟踪文件在上次提交后都未被更改过。
git status
On branch master
nothing to commit, working directory clean
  1. 现在让我们修改一下,比如添加一个文件(注意:需要在git克隆的仓库内执行)
vim README

然后随便输入一些内容保存退出。

git status

会出现:Untracked files ,即未跟踪状态

Untracked files:
(use "git add <file>..." to include in what will be committed)
README

nothing added to commit but untracked files present (use "git add" to track)

表示我们的README 处于Untracked files即未跟踪状态

未跟踪的文件意味着Git在之前的快照(提交)中没有这些文件;Git 不会自动将之纳入跟踪范围,除非你明明白白地告诉它“我需要跟踪该文件”,因而不用担心把临时文件什么的也归入版本管理。

2.2 跟踪新文件

跟踪我们上面新建的 README文件:

git add README

当我们再次 git status,会发现它处于:

**Changes to be committed,即未提交状态,它这时已经被跟踪了,但是没有提交。**即处于暂存状态

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: README

其实 git add 的作用就是将一个文件放入暂存区域中,并且把所有未跟踪的文件或者目录变为已跟踪状态。

这是个多功能命令,根据目标文件的状态不同,此命令的效果也不同:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等这是个多功能命令,根据目标文件的状态不同,此命令的效果也不同:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等

2.3 暂存已修改的文件

我们修改一个已经存在于历史版本的文件:README.mkd

忽略上面的内容,我们会看到这样的状态:Changes not staged for commit

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: README.mkd

表示已经跟踪的文件发生了修改,但是还没有放在暂存区里。

要暂存这次更新,则需要执行git add(看上节关于git add的讲解)命令。

现在我们运行此命令把 README.mkd放到暂存区中:

git add README.mkd

再次status其状态得到:

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: README
modified: README.mkd

两个文件都被放在暂存区了,提交后便会被更新到仓库中


注意:如果此时你又想修改一个已经被放在暂存区的文件,则修改后会发现,出现了两个相同的文件,一个已跟踪并且放在暂存区,而另一个已跟踪未在暂存区。

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: README
modified: README.mkd

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: README.mkd

这是因为 git只会暂存 执行git add后的文件,因此此时需要重新 输入此命令

git add README.mkd
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: README
modified: README.mkd

2.4 忽略某些文件

我们不想让某些文件被纳入git的管理,即他们根本不用出现在未跟踪状态下

我们创建或者修改一下 .gitignore 文件即可

vim .gitignore

修改后,查看文件如下:

$ cat .gitignore
*.gem
*.swp
*.[oa]
*~
*.log
*.tmp
*.pid
rdoc/
pkg/
  1. *.gem *.swp *.[oa] 表示我们要忽略以 gem swp o a 等后缀的文件
  2. ~ 表示 一些文件的副本,或者其他文件
  3. rdoc/ 表示的是一个 文件夹,因为它的末尾是 /

要养成一开始就设置好 .gitignore 文件的习惯,以免将来误提交这类无用的文件。(可以对一些模式取反,表示的就是忽略他们之外的文件或者目录)

2.5 查看已暂存或者未暂存的更新

查看具体修改了什么地方,可以使用下面的命令:

git diff

运行如下:

diff --git a/README b/README
index e31a6eb..0a7d6e9 100644
--- a/README
+++ b/README
@@ -1,3 +1,4 @@
你好!6
6666
hjhhhh
+我修改了一行

前面的 + 号表示我们添改了这一行的内容,- 号则表示我们删改了一行信息

此命令比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改了之后还没有暂存起来的变化


查看已经暂存的文件与上次提交的文件的差异:

首先把README先 放入暂存区

git add README

运行如下命令:即可查看

git diff --cached

简单总结:

  1. git diff:查看某个文件还没有被暂存起来的改动,其实就是显示你当前修改了什么内容,与在暂存区的内容做比较。暂存前后的变化
  2. git diff --cached:查看某个文件已经被暂存和上一次提交时的文件的内容差异。已经暂存的变化

2.6 提交更新

首先检查有没有修改了但是没有被暂存的,因为提交只会提交暂存区的

检查:

git status
git add xxx # 如果还存在未暂存的目标

检查完成后,输入提交命令:

git commit

这时就会出现一个文本编辑器,并且输入本次提交的说明

我的出现了 vscode,可以按照下列的命令进行修改默认哪个编辑器:

git config --global core.editor xxxxx

默认的提交信息包括最后一次git status显示的信息

如果觉得这还不够,可以用 -v 选项将修改差异的每一行都包含到注释中来。

退出编辑器时,Git 会丢掉注释行,将说明内容和本次更新提交到仓库。

在空行输入提交信息:保存后退出

learning git use

接着就会提示你提交成功!并且显示当前是在哪个分支(master)提交的,本次提交的完整 SHA-1 校验和是什么(582f005),以及在本次提交中,有多少文件修订过,多少行添改和删改过。

[master 582f005] learning git use
3 files changed, 10 insertions(+), 1 deletion(-)
create mode 100644 README

提交时记录的是放在暂存区域的快照,任何还未暂存的仍然保持已修改状态,可以在下次提交时纳入版本管理。每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较。

使用 -m 快速添加提交信息

git commit -m 我要学习

[master f949baa] 我要学习
1 file changed, 2 insertions(+)

2.7 跳过暂存

使用下面的命令可以将修改的文件无需放入暂存区,即无需使用git add的命令,可以直接 提交。

修改了一个文件之后,执行下面的语句:

git commit -a

即在commit的时候添加一个 -a 2.

实现快速修改提交:

git commit -a -m 跳过暂存
[master 042500c] 跳过暂存
1 file changed, 2 insertions(+)

2.8 移除文件

从 Git 中移除某个不想要的文件,即从已经暂存的区域移除某个文件。

输入以下命令,来删除暂存区的文件,并且直接把它从工作目录中删除,连未跟踪区域都别留下。

git rm xxx

相当于直接删除这个文件

Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: README

如果要删除一个已经放在暂存区的文件,则必须强制删除,输入以下命令:

git rm -f xxx

只从暂存区删除,即删除跟踪,但是不删除其本身

git rm --cached xxx

此命令删除所有 log/ 目录下扩展名为 .log 的文件

git rm log/\*.log

删除当前目录及其子目录中所有 ~ 结尾的文件。

git rm \*~

2.9 移动文件

我们想要把一个文件README.txt 改为 README ,可以使用下面的命令:

git mv README.txt README

mv 表示 把文件从README.txt 改为 README

实际上执行了三条语句是等价的:注意README.txt一定是在暂存区域内

mv README.txt README
git rm README.txt
git add README
  1. mv命令把README.txt 改为 README,但是此时README.txt仍在暂存区,并且README在未暂存区
  2. 删除暂存区的README.txt
  3. 把README放入暂存区

实际上 git mv file_from file_to 便可以表示这一过程,无需写三条

3. 查看提交历史

演示: 首先运行命令获取项目库

git clone git://github.com/schacon/simplegit-progit.git

在此项目中运行:

git log

会出现以下内容:

commit ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD)
Author: Scott Chacon <schacon@gmail.com>
Date: Mon Mar 17 21:52:11 2008 -0700

changed the verison number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 16:40:33 2008 -0700

removed unnecessary test code

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gmail.com>
Date: Sat Mar 15 10:31:28 2008 -0700

first commit

git log 会按提交时间列出所有的更新,最近的更新排在最上面

每次更新都有一个 SHA-1 校验和,作者姓名电子邮箱,提交时间与提交说明


使用 -p 显示每次提交的内容差异 -2只显示最近两次:

git log -p -2

使用--word-diff获取单词层面的变化

git log -p --word-diff

使用-stat 显示简要的增改行数统计

git log --stat

每个提交都列出了修改过的文件,以及其中添加和移除的行数,并在最后列出所有增减行数小计。


--pretty 可以指定使用完全不同于默认格式的方式展示提交历史

git log --pretty=xxx

xxx可以为:oneline,short,full,fuller

format 定制显示的格式,相当于debug

git log --pretty=format:"%h - %an, %ar : %s"

说明:
选项 说明 %H 提交对象(commit)的完整哈希字串 %h 提交对象的简短哈希字串 %T 树对象(tree)的完整哈希字串 %t 树对象的简短哈希字串 %P 父对象(parent)的完整哈希字串 %p 父对象的简短哈希字串 %an 作者(author)的名字 %ae 作者的电子邮件地址 %ad 作者修订日期(可以用 -date= 选项定制格式) %ar 作者修订日期,按多久以前的方式显示 %cn 提交者(committer)的名字 %ce 提交者的电子邮件地址 %cd 提交日期 %cr 提交日期,按多久以前的方式显示 %s 提交说明


log 的后面参数的其他选择

选项 说明 -p 按补丁格式显示每个更新之间的差异。 --word-diff 按 word diff 格式显示差异。 --stat 显示每次更新的文件修改统计信息。 --shortstat 只显示 --stat 中最后的行数修改添加移除统计。 --name-only 仅在提交信息后显示已修改的文件清单。 --name-status 显示新增、修改、删除的文件清单。 --abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。 --relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。 --graph 显示 ASCII 图形表示的分支合并历史。 --pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。 --oneline `--pretty=oneline --abbrev-commit` 的简化用法


--since 和 --until 对时间作出限制

显示最近两周的提交:

git log --since=2.weeks

其他选择:

选项 说明 -(n) 仅显示最近的 n 条提交 --since, --after 仅显示指定时间之后的提交。 --until, --before 仅显示指定时间之前的提交。 --author 仅显示指定作者相关的提交。 --committer 仅显示指定提交者相关的提交。

4. 撤销操作

4.1 修改最后一次操作

如果在提交后,发现提交信息写错了,或者漏掉几个文件没有加,则可以这样修改:

git commit --amend

如果还没有暂存文件就提交了,则可以这样操作:

git commit # 提交了
git add file
git commit --amend

上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。

4.2 取消暂存中的文件

我们有多个文件还未暂存,但是我们不小心一次性全部放入暂存了:

git add .

但是我们想一个一个放,不能一次性放入,因此我们使用这两条命令(git status显示的内容有说明):

git reset HEAD file

HEAD表示上一个版本 HEAD^ HEAD^^ ....

git store --staged file

4.3 取消对文件的修改

我们不想对这个文件进行修改了,让他回到一开始的状态:

git checkout -- benchmarks.rb

你可能已经意识到了,这条命令有些危险,所有对文件的修改都没有了,因为我们刚刚把之前版本的文件复制过来重写了此文件。所以在用这条命令前,请务必确定真的不再需要保留刚才的修改。如果只是想回退版本,同时保留刚才的修改以便将来继续工作,可以用下章介绍的 stashing 和分支来处理,应该会更好些。

5. 远程管理仓库

管理远程仓库的工作,包括添加远程库,移除废弃的远程库,管理各式远程库分支,定义是否跟踪这些分支

5.1 查看当前远程库

查看当前配置有哪些远程库

git remote

注意:默认存在一个 origin的远程库,Git 默认使用这个名字来标识你所克隆的原始仓库。

显示原始仓库的克隆地址

git remote --v

如果有多个远程仓库,此命令将全部列出。

5.2 添加远程仓库

要添加一个新的远程仓库,可以指定一个简单的名字,以便将来引用:

git remote add pb  git://github.com/paulboone/ticgit.git

添加了一个 远程仓库 名称为 pb

pb代表的就是远程仓库的地址

抓取仓库地址:

git fetch pb

Paul 的主干分支(master)已经完全可以在本地访问了,对应的名字是 pb/master,你可以将它合并到自己的某个分支,或者切换到这个分支,看看有些什么有趣的更新。

5.3 从远程仓库抓取数据

使用下面的命令从远程仓库抓取数据到本地:

git fetch <remote-name>

此命令从远程仓库中拉取所有你本地仓库中还没有的数据。


抓取从你上次克隆这个仓库以来,别人上传到此仓库中的所有更新:

git fetch origin

有一点很重要,需要记住,fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。

5.4 推送数据到远程仓库

项目进行到一个阶段,要同别人分享目前的成果,可以将本地仓库中的数据推送到远程仓库。

git push [remote-name] [branch-name]

把本地的branch分支推送到远程 remote 服务器上

5.5 查看远程仓库信息

命令:

git remote show [remote-name]

查看某个远程仓库的信息

它友善地告诉你如果是在 master 分支,就可以用 git pull 命令抓取数据合并到本地。

另外还列出了所有处于跟踪状态中的远端分支。

5.6 远程仓库的删除与重命名

修改某个远程仓库在本地的名称

git remote rename pb pbnewname

对远程仓库的重命名,也会使对应的分支名称发生变化。

删除对应的远程仓库:

git remote rm pbname

6. 打标签

在某一时间点上打上标签

git的标签类型:

  1. 轻量型标签:是个不会变化的标签,只指向某个特定对象的引用
  2. 含附注的标签:存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明。

6.1 显示所有标签

git tag

标签按字母顺序排列,所以标签的先后不表示重要程度的轻重.

筛选标签

git tag -l 'v1.4.2.*'

6.2 创建标签

创建含附注的标签:-a 后附带标签的名字

git tag -a v1.4 -m 'my version 1.4'

-m表示指定对应的标签说明,如果没有 -m后面的内容,则会跳转到vscode让你手动编写 标签说明

使用下面的命令来显示标签对应的信息:

git show v1.4

列出了此标签的提交者和提交时间,以及相应的标签说明。

创建个人的私钥:

git tag -s v1.5 -m 'my signed 1.5 tag'

创建轻量级标签,直接给出标签的名字即可

git tag v1.8

6.3 加注标签

已经提交的版本中补上标签信息:

首先显示所有的版本

git log --pretty=oneline

可以看到 没有标签,我们输入命令,让其中一个版本加上标签:

git tag -a v1.9 085bb3b

注意:直需要加上校验和的前几位即可,git就会识别这是哪一个版本。

显示我们刚加的标签:

git show v1.9

6.4 分享标签

通过显式命令才能分享标签到远端仓库。其命令格式如同推送分支,运行 git push origin [tagname] 即可:

git push origin v1.5

一次性推送所有的本地标签上去:

git push origin --tags

7. Git使用技巧

7.1 自动补全

首先可以查看自己的 Git 有没有自动补全的功能,如下操作所示:

git con<tab>

输入git co 然后 按两次tab键,会出现提示的命令: config 和commit



Git学习入门(2)- 基本命令操作总结


如果上述办法不可以,则需要进行如下操作:

如果你用的是 Bash shell,可以试试看 Git 提供的自动补全脚本。下载 Git 的源代码,进入 contrib/completion 目录,会看到一个 git-completion.bash 文件。将此文件复制到你自己的用户主目录中(译注:按照下面的示例,还应改名加上点:cp git-completion.bash ~/.git-completion.bash),并把下面一行内容添加到你的 .bashrc 文件中:
source ~/.git-completion.bash
也可以为系统上所有用户都设置默认使用此脚本。Mac 上将此脚本复制到 /opt/local/etc/bash_completion.d 目录中,Linux 上则复制到 /etc/bash_completion.d/ 目录中。这两处目录中的脚本,都会在 Bash 启动时自动加载。

7.2 使用别名

为命令起一个别名: git config

git config --global alias.st status

接下来输入

git st

其实就是

git status

取消在暂存区的文件:完整命令如下:

git reset HEAD file

可以使用别名:

git config --global alias.unstage 'reset HEAD --'
git unstage file

显示最后一次提交的文件,完整命令如下:

git log -1 HEAD

可以使用别名,看起来会更清晰

git config --global alias.last 'log -1 HEAD'
git last

Git 只是简单地在命令中替换了你设置的别名

输入Git外部命令

git config --global alias.visual '!gitk'
git visual