​今天学习了一些git的相关命令和一些基础的信息。
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目,它与svn有很大的不同。

  • SVN
    svn有一个公共的资源库,这个资源库的资源是对所有用户开放的,单个用户可以远程获取它,如果用户对它进行一些修改然后提交,那么这个资源库发生更新,那么其他的用户也可以在连接资源库时,得到更新后的内容。
  • Git
    用户拥有单独的资源库,这些库之间是连同的,如果一个用户想要更新别人的资源库,可以在修改、更新后连接别人的资源库,然后进行提交。那么别人的资源库就发生改变,对项目的协同合作有很大的便利性。

Git

Git 工作区、暂存区和版本库


  • 工作区:就是你在电脑里能看到的目录。
  • 暂存区:英文叫stage, 或index。一般存放在 ".git目录下"下的index文件(.git/ index)中,所以我们把暂存区有时也叫作索引(index)。
  • 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

图中的 objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,里面包含了创建的各种对象及内容。
当对工作区修改(或新增)的文件执行"gitadd"命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
当执行 “git reset HEAD” 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
当执行 “git rm --cached ” 命令时,会直接从暂存区删除文件,工作区则不做出改变。
当执行 “git checkout .” 或者 "git checkout --file的指令,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
当执行 “git checkout HEAD .” 或者 “git checkout HEAD ” 命令时,会用HEAD指向的master分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

Git命令

  • git init
    该命令执行完后会在当前目录生成一个 .git目录,这就是你的Git仓库。
  • git init newrepo
    使用我们指定目录作为Git仓库。
  • git clone
1
2
3
4
5
$ git clone git://github.com/schacon/grit.git
执行该命令后,会在当前目录下创建一个名为grit的目录,其中包含一个 .git 的目录,用于保存下载下来的所有版本记录。
git clone git@github.com:fsliurujie/test.git --SSH协议
git clone git://github.com/fsliurujie/test.git --GIT协议
git clone https://github.com/fsliurujie/test.git --HTTPS协议
  • git add
    git add 命令可将该文件添加到缓存
1
2
3
4
5
6
7
8
9
10
$ git add README hello.php
我们再执行git status,就可以看到这两个文件已经加上去了。
$ git status -s
A README
A hello.php
在 README 添加以下内容:# Runoob Git 测试,然后保存退出。
$ git status -s
AM README
A hello.php
"AM" 状态的意思是,这个文件在我们将它添加到缓存之后又有改动。

git add . 命令来添加当前项目的所有文件。

  • git status
    git status 查看在你上次提交之后是否有修改,该命令的后面加了 -s 参数,可以获得简短的结果输出。
1
2
3
4
5
6
7
8
9
10
$ git status
On branch master

Initial commit

Changes to be committed:
(use "git rm --cached <file>..." to unstage)

new file: README
new file: hello.php
  • git diff
    尚未缓存的改动:git diff
    查看已缓存的改动: git diff --cached
    查看已缓存的与未缓存的所有改动:git diff HEAD
    显示摘要而非整个 diff:git diff --stat
    1.git diff
1
2
3
4
5
6
7
8
9
10
11
hello.php 文件中输入以下内容<?php echo '菜鸟教程:www.runoob.com';
?>
$ git diff
diff --git a/hello.php b/hello.php
index e69de29..69b5711 100644
--- a/hello.php
+++ b/hello.php
@@ -0,0 +1,3 @@
+<?php
+echo '菜鸟教程:www.runoob.com';
+?>

2.git diff --cacheds

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
把hello.php 、rename 写入缓存。
$ git diff --cached
diff --git a/README b/README
new file mode 100644
index 0000000..8f87495
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+# Runoob Git 测试
diff --git a/hello.php b/hello.php
new file mode 100644
index 0000000..69b5711
--- /dev/null
+++ b/hello.php
@@ -0,0 +1,3 @@
+<?php
+echo '菜鸟教程:www.runoob.com';
+?>
  • git commit
    1
    2
    3
    4
    5
    $ git commit -m '第一次版本提交'
    [master (root-commit) d32cf1f] 第一次版本提交
    2 files changed, 4 insertions(+)
    create mode 100644 README
    create mode 100644 hello.php

如果你觉得git add提交缓存的流程太过繁琐,Git也允许你用-a选项跳过这一步

1
2
3
git commit -am '修改 hello.php 文件'
[master 71ee2cb] 修改 hello.php 文件
1 file changed, 1 insertion(+)
  • git reset HEAD 用于取消已缓存的内容
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    修改rename、hello.php后,提交到缓存区,然后取消hello.php的缓存。
    $ git add .
    $ git status -s
    M README
    M hello.php
    $ git reset HEAD hello.php
    Unstaged changes after reset:
    M hello.php
    现在执行git commit,只会将README文件的改动提交,而hello.php是没有的。
    $ git commit -m '修改'
    [master f50cfda] 修改
    1 file changed, 1 insertion(+)
    $ git status -s
    M hello.php
    简而言之,执行gitresetHEAD以取消之前gitadd添加,但不希望包含在下一提交快照中的缓存。
    注意:红色‘M’是修改但未缓存,绿色‘M’是修改后缓存了。
  • git rm
1
2
3
4
git rm <file>            从Git中移除某个文件,这个文件未被放到缓存去。
git rm -f <file> 之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f。
git rm --cached <file> 只把文件从暂存区域移除,当前工作目录中保留有它。
git rm –r * 可以递归删除,即如果后面跟的是一个目录做为参数,则会递归删除整个目录中的所有子目录和文件。
  • git mv
    用于移动或重命名一个文件、目录、软连接。
1
2
3
$ git mv README  README.md
$ ls
README.md

Git 分支管理

  • git branch (branchname) 创建分支命令
  • git checkout (branchname)切换分支命令
  • git merge 合并分支命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
git branch   没有参数时,git branch会列出你在本地的分支。
$ git branch testing
$ git branch
* master
testing
此时创建的新分支和之前的master内容是一样的。
$ git checkout testing
Switched to branch 'testing'
$ ls
README
此时切换到testing分支。
$ git checkout -b newtest
Switched to a new branch 'newtest'
$ git rm test.txt
rm 'test.txt'
$ ls
README
可以使用 git checkout -b (branchname) 命令来创建新分支并立即切换到该分支下,从而在该分支中操作。
使用分支将工作切分开来,从而让我们能够在不同开发环境中做事,并来回切换。
  • 删除分支
1
2
3
4
5
git branch -d (branchname)  删除分支命令。
$ git branch -d testing
Deleted branch testing (was 85fc7e7).
$ git branch
* master
  • 分支合并
1
2
3
4
5
6
7
8
9
10
11
git merge
某分支有了独立内容,可以使用这个命令将任何分支合并到当前分支中。
$ git merge newtest
Updating 3e92c19..c1501a2
Fast-forward
runoob.php | 0
test.txt | 1 -
2 files changed, 1 deletion(-)
create mode 100644 runoob.php
delete mode 100644 test.txt
合并,就是把分支中的修改的操作放到主分支中。合并结束后,可以删除分支。
  • 合并冲突
    我们创建两个及以上的分支时,在两个不同的分支上进行不同的操作,然后把两个分支合并到一起时,直接使用git merge命令进行合并时会发生合并冲突。
    接下来我们需要手动去修改它。
    要去把其中一个分支病机上另一个,即补上另一个分支的不同操作。
    最后可以用git add写入缓存,告诉Git文件冲突已经解决,然后提交结果。

  • Git 查看提交历史
    想回顾下提交历史,我们可以使用git log命令查看

1
2
3
4
5
6
7
8
9
10
11
12
13
$ git log
commit d5e9fc2c811e0ca2b2d28506ef7dc14171a207d9 (HEAD -> master)
Merge: c68142b 7774248
Author: runoob <test@runoob.com>
Date: Fri May 3 15:55:58 2019 +0800

Merge branch 'change_site'

commit c68142b562c260c3071754623b08e2657b4c6d5b
Author: runoob <test@runoob.com>
Date: Fri May 3 15:52:12 2019 +0800

此命令得到历史提交记录是非常详细的。

oneline 选项是用来查看历史记录的简洁的版本

1
2
3
4
5
6
7
$ git log --oneline
d5e9fc2 (HEAD -> master) Merge branch 'change_site'
c68142b 修改代码
7774248 (change_site) changed the runoob.php
c1501a2 removed test.txt、add runoob.php
3e92c19 add test.txt
3b58100 第一次版本提交

还可以用 --graph 选项,查看历史中什么时候出现了分支、合并

1
2
3
4
5
6
7
8
9
git log --graph --oneline
* d5e9fc2 (HEAD -> master) Merge branch 'change_site'
|\
| * 7774248 (change_site) changed the runoob.php
* | c68142b 修改代码
|/
* c1501a2 removed test.txt、add runoob.php
* 3e92c19 add test.txt
* 3b58100 第一次版本提交

也可以用 --reverse 参数来逆向显示所有日志

1
2
3
4
5
6
7
$ git log --reverse --oneline
3b58100 第一次版本提交
3e92c19 add test.txt
c1501a2 removed test.txt、add runoob.php
7774248 (change_site) changed the runoob.php
c68142b 修改代码
d5e9fc2 (HEAD -> master) Merge branch 'change_site

查找指定用户的提交日志:git log --author , 例如,比方说我们要找Git源码中Linus提交五个的记录

1
2
3
4
5
6
$ git log --author=Linus --oneline -5
81b50f3 Move 'builtin-*' into a 'builtin/' subdirectory
3bb7256 make "index-pack" a built-in
377d027 make "git pack-redundant" a built-in
b532581 make "git unpack-file" a built-in
112dd51 make "mktag" a built-in

如果要指定日期,可以执行几个选项:–since 和 --before,但是你也可以用 --until 和 --after。

1
$ git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges
  • Git 标签
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ git tag -a v1.0
a 选项意为"创建一个带注解的标签"。
如果我们忘了给某个提交打标签,又将它发布了,我们可以给它追加标签。
获取日志记录,选取85fc7e7(上面实例最后一行)
$ git tag -a v0.9 85fc7e7
$ git log --oneline --decorate --graph
* d5e9fc2 (HEAD -> master) Merge branch 'change_site'
|\
| * 7774248 (change_site) changed the runoob.php
* | c68142b 修改代码
|/
* c1501a2 removed test.txt、add runoob.php
* 3e92c19 add test.txt
* 3b58100 (tag: v0.9) 第一次版本提交

查看所有标签

1
2
3
4
5
$ git tag
v0.9
v1.0
指定标签信息命令
git tag -a <tagname> -m "runoob.com标签"

使用SSH方式连接远程仓库

1. 生成SSH公钥
ssh-keygen -t rsa -C "raoweijiapng"
2. 输入密码,如果为空代表以后提交信息到仓库的时候,不用再次输入密码,那当然为空最好。
验证是否设置成功:
ssh -T git@github.com
3. 将id_rsa.pub数据复制到github设置SSH设置中,登录后一次点击settings->SSH and GPG keys->New SSHkey,然后将填写key的名称,将id_rsa.pub文件的内容全部复制到填写公钥的输入框中即可。
4. 设置全局的user.name user.email 
$ git config user.name "dadi" 
$ git config user.email "123123123@qq.com"
5. 添加别名,别名绑定的远程仓库地址是SSH方式的地址
如果别名已经存在,我们要先删除,再重新添加。
git remote rm mystore
git remote add mystore "git@github.com:18357136930/chenycstore.git"
最后就可以使用git命令和远程仓库进行交互。