博客源为书写的载体,书写以对思维的缓存 正文

Git笔记


Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目,功能强大老少皆宜。写这篇文章主要是做个笔记毕竟好记性不如烂笔头。

1.安装Git

sudo apt-get install git    # 我是Ubuntu

安装完成后可通过命令git --version查看安装的版本。另外还需要设置一下个人信息,输入如下命令:

git config --global user.name "username"            # 设置一个用户名
git config --global user.email email@example.com    # 设置邮箱,不需要双引号

git config:专门用来配置或读取相应的工作环境变量,配合--global参数则表示读取的是~/.gitconfig文件,不过我的路径是在/root/.gitconfig。

其它命令:

git config --list    #查看已有的配置信息
git config --global core.editor emacs    # 将编辑器更改为emacs,默认为Vim

2.创建/获取本地仓库

Git有两个工作库:本地仓库和远程仓库。

本地仓库说白了就是一个目录,这个目录里面的所有文件都可以被Git管理起来。每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

远程仓库就是一个服务器,提供Git仓库托管服务的,通常我们将GitHub网站作为我们的远程仓库。

一:创建命令

git init

通过这个命令就可以把你当前所在的目录变成本地仓库。然后目录里就会生成一个.git子目录这个目录是Git来跟踪管理版本库的,不要轻易更改里面的文件。

二:获取命令

git clone [url]

获取主要是从远程仓库来获取,比如获取GitHub上已有的项目:

git clone https://github.com/Chris-iron/blog

这会在当前目录下创建一个名为blog的目录,并在这个目录下初始化一个 .git 文件夹,从远程仓库拉取下所有数据放入 .git 文件夹,然后从中读取最新版本的文件的拷贝。另外如果你想在克隆远程仓库的时候,自定义本地仓库的名字,你可以使用如下命令:

git clone https://github.com/Chris-iron/blog myblog

3.本地仓库的操作

本地仓库分为三部分:工作区,暂存区,仓库区,它们之间的操作示意图如下:

git0.jpg

可以看到有两条主线,我自定义为提交主线(工作区-->暂存区-->仓库区)和回退主线(仓库区-->暂存区-->工作区)。

一:提交主线相关命令

1.将文件添加到暂存区:

git add 文件1,文件2

2.将暂存区的记录提交到仓库区

git commit -m "本次提交说明"

3.查看暂存区的状态(记录)

git status

4.如有文件进行了修改,查看修改详情

git diff 文件名    # 未加入缓存区(工作区的修改)
git diff --cached 文件名    # 已加入缓存区(缓存区中的修改)

5.查看工作区和版本库里面最新版本的区别

git diff HEAD -- 文件名

二:回退主线相关命令

1.查看仓库区的版本历史

>>> git log    # 标准输出信息

... commit 096a605ac710a7fd4ed21d88f5b67ea8ce5d290f 
... Author: caodahua <18515104346@163.com>
... Date:   Thu Nov 22 14:05:18 2018 +0800
...     第一次版本提交
... commit 702a120bd8d37984d7da29f399c60d00abf41d81
... Author: caodahua <18515104346@163.com>
... Date:   Thu Nov 22 15:52:03 2018 +0800
...     第二次版本提交
----------------------------------------------------
>>> git log --pretty=oneline    # 简版输出信息

... 702a120bd8d37984d7da29f399c60d00abf41d81 第二次版本提交
... 096a605ac710a7fd4ed21d88f5b67ea8ce5d290f 第一次版本提交
----------------------------------------------------

2.回退历史版本到暂存区

git reset --hard HEAD^或版本号    # 版本号写前几位就行了如:702a120

在Git中,用HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。版本号就是上面那些一串数字和英文字母。

如果回退到上一个版本,那么在git log时就不会再显示当前的版本信息了,例如当前版本为"版本2",进行回退到"版本1",完成后使用git log命令则只会显示"版本1"的信息。如果几天后你又想回退到"版本2",此时你无法使用HEAD来回退,只能通过版本号。但是git log已经查不到"版本2"的信息了,所以此时你需要git reflog命令:

>>> git reflog    # 历史命令

... 702a120 HEAD@{2}: commit: 第二次版本提交
... 096a605 HEAD@{3}: commit (initial): 第一次版本提交

git reflog命令会查询出你所有的关于提交和回退的信息,信息中包括版本号以及提交说明。

3.撤销功能

git checkout -- 文件名

如果你在工作区中修改了文件且未添加到缓存区,则此撤销会将该文件恢复到最新版本。

如果修改了并且已经添加到了缓存区,则此命令无效。你需要分别执行以下命令:

git reset HEAD 文件名
git checkout -- 文件名

git reset不仅可以回退版本,还可以将添加到暂存区的文件回退到工作区。HEAD代表最新的版本。你需要先通过此命令将文件回退到工作区然后再使用"git checkout -- 文件名"命令撤销修改。(你可能看的晕了,试着实践一下你就明白了。)

撤销总结:

场景1:当你改乱了工作区某个文件的内容,想直接撤销工作区的修改时,用命令"git checkout -- 文件名"。
场景2:当你不但改乱了工作区某个文件还添加到了暂存区时,想撤销修改分两步:第一步用命令"git reset HEAD 文件名"
      就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,那么就版本回退,不过前提是没有推送到远程库。

三:删除命令

1.文件没有add至暂存区

rm 文件名    # 直接删除

2.文件已经add至暂存区

rm 文件名
git rm 文件名

3.文件已经add暂存区并且也commit至仓库区

rm 文件名
git rm 文件名
git commit -m "提交说明"

4.只从暂存区中删除

git rm --cached 文件名

4.与远程仓库交互(GitHub)

1.本地仓库与远程仓库进行关联

git remote add origin git@github.com:Chris-iron/git-test.git

2.从远程仓库下载分支

git fetch    # 所有分支
git fetch <远程主机名> <分支名>    # 指定分支

3.从远程仓库同步更新分支(下载fetch+合并merge):git pull

1.将指定的远程分支更新到"指定的"本地分支
    git pull <远程主机名> <远程分支>:<本地分支>

2.将指定的远程分支更新到"当前所在的"本地分支
    git pull <远程主机名> <远程分支>
  
3.如果远程分支和本地分支已建立了追踪关系(tracking),会自动选择关联的两两分支进行更新
    git pull <远程主机名>
  建议使用这种方式,这样可以避免繁琐的命令。
  
  建立追踪关系命令:
    git branch --set-upstream-to=<远程主机名>/<远程分支> <本地分支>
  例如:
    git branch --set-upstream-to=origin/dev dev

4.如果当前分支只有一个追踪分支,可省略<远程主机名>
    git pull

4.本地分支推送到远程仓库:git push

1.将"指定的"本地分支推送到指定的远程分支
    git push <远程主机名> <本地分支>:<远程分支>
    
2.注意一点:如果本地分支名未填写,则表示删除指定的远程分支
    git push <远程主机名> :<远程分支>
    
3.如果两地分支存在"追踪关系",则本地分支和远程分支可以省略不写
    git push <远程主机名>
    
4.如果当前分支只有一个追踪分支,那么主机名也可以省略。
    git push
    
5.如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机
    git push -u <远程主机名> <本地分支>
  例如:
    git push -u origin dev
  上面命令表示将本地的dev分支推送到origin主机同时指定origin为默认主机,后面就可以不加任何参数直接使用git push了。

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

git remote       # 返回远程主机名
git remote -v    # 每个主机名的详细链接地址

6.删除远程仓库

git remote rm <远程主机名>

5.分支管理

分支可以让你从开发主线上分离开来,然后在不影响主线的同时继续工作。

1.创建分支,切换分支

git branch 分支名        # 创建分支
git checkout 分支名      # 切换分支 
缩写:
git checkout -b 分支名   # 创建+切换

2.查看所有分支,当前分支前面会标一个*号。

git branch

3.合并分支:

git merge 分支名    # 合并指定分支到当前分支

4.删除分支

git branch -d 分支名    # 分支已被合并
git branch -D 分支名    # 分支未被合并

5.隐藏/恢复任务

git stash         # 隐藏

git stash list    # 查看隐藏记录
例如:
stash@{0}: WIP on dev: f52c633 add merge
stash@{1}: WIP on dev: d22c351 add merge

git stash apply stash@{0}     # 恢复任务{0}
git stash drop stash@{0}      # 除掉记录{0},恢复之后通常需要删除掉记录

6.合并冲突

合并分支最常见的问题就是发生冲突了,如何解决冲突让我头发都掉了好几根。

一:内容冲突

对同一文件的同一块区域进行了修改,进行合并时就会提示内容冲突,我们最常见的就是这种了。

解决思路:

  1. 1.git status命令查看冲突信息:

  2. 例如:
    root@caodahua:/home/project/mygit# git status
    On branch master
    Your branch is ahead of 'origin/master' by 1 commit.
      (use "git push" to publish your local commits)
    You have unmerged paths.
      (fix conflicts and run "git commit")
    
    Unmerged paths:
      (use "git add <file>..." to mark resolution)
    
     both modified:   test.txt    # 提示信息

    2.根据提示信息,到相应的文件中查看,会发现文件中有以下错误提示:

  3. <<<<<<< HEAD
    主分支master添加的内容
    =======
    分支dev添加的内容
    >>>>>>> dev

    Git用<<<<<<<,=======,>>>>>>>三种冲突标示符标记出不同分支的内容,其中=======上面是当前分支"master"的代码,=======下面是要合并进来的分支"dev"的代码,两者发生了冲突。此时分析两段代码是实现相同功能,还是各自实现的不同功能。

  4. 如果是相同功能:两个二选一删除一个,然后再把这些冲突标示符删除即可;如果不是相同功能:两个都需要保留,只把冲突标示符删除即可。

  5. 3.完成后执行add暂存区,commit仓库区。

  6. git add test.txt
    
    git commit -m "冲突已解决"

    4.可以通过git log --graph --pretty=oneline命令查看分支的合并情况

  7. root@caodahua:/home/project/mygit# git log --graph --pretty=oneline
    *   941b8e4e11562629f44fb705f9d3dfb73ddfecae 冲突已解决
    |\
    | * e3351505e359f12527896a3928d491cb9b484d19 dev提交
    * | f9690ba41af16481b150377afbd58f905419e676 主分支提交
    |/

    5.最后,删除dev分支

  8. git branch -d dev

二:树冲突

文件名修改造成的冲突称之为树冲突,也就是对同一文件修改了不同的文件名,当你进行合并时就会产生冲突了。

解决思路:

  1. git rm a.txt
    git rm origin-name.txt
    git add b.txt
    git commit -m "已解决树冲突"

7.标签管理

1.创建标签

git tag <标签名>    # 标签默认是打在最新提交的commit上
git tag <标签名> <commit版本号>    # 给指定的commit设置标签
git tag -a <标签名> -m "标签说明" <commit版本号>    # 设置标签说明

2.查看标签

git tag    # 查看所有标签
git show <标签名>    # 查看指定标签的详细信息

3.删除标签

git tag -d <标签名>

4.推送标签到远程库

git push <远程主机名> <标签名>    # 推送指定标签
git push <远程主机名> --tags     # 推送所有标签

5.删除远程库中的标签(2步骤)

1.git tag -d <标签名>    # 先删除本地标签
2.git push <远程主机名> :<路径/标签名>    # 再删除远程库中的标签

最后

1464.jpg