Git使用教程

基本背景

Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的分布式版本控制系统。
它采用了分布式版本库的方式,不必服务器端软件支持(注:这得分是用什么样的服务端,使用http协议或者git协议等不太一样。并且在push和pull的时候和服务器端还是有交互的),使源代码的发布和交流极其方便。

Git与SVN区别

Git 不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。

如果你是一个具有使用 SVN 背景的人,你需要做一定的思想转换,来适应 Git 提供的一些概念和特征。

Git 与 SVN 区别点,这里借用菜鸟教程的一张图说明:

图片名称
1、Git 是分布式的,SVN 不是:这是 Git 和其它非分布式的版本控制系统,例如 SVN,CVS 等,最核心的区别。

2、Git 把内容按元数据方式存储,而 SVN 是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似 .svn、.cvs 等的文件夹里。

3、Git 分支和 SVN 的分支不同:分支在 SVN 中一点都不特别,其实它就是版本库中的另外一个目录。

4、Git 没有一个全局的版本号,而 SVN 有:目前为止这是跟 SVN 相比 Git 缺少的最大的一个特征。

5、Git 的内容完整性要优于 SVN:Git 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。

安装

window下的安装及海龟Git的安装配置

参考window下git及TortoiseGit的安装

Centos/Redhat系列安装

在终端下执行 yum install git

Ubuntu/Debian系列安装

在终端下执行 apt-get install git 

编译安装

在https://github.com/git/git/releases 上选取一个版本下载,解压缩后进入到 Git 的目录然后依次执行以下代码:

make configure
./configure
make all
sudo make install

代码管理

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

  • 工作区:就是你在电脑里能看到的工作目录,某个项目文件夹。
  • 暂存区:英文叫stage, 或index。一般存放在 ".git目录下" 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
  • 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库
图片名称
图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage, index),标记为 "master" 的是 master 分支所代表的目录树。

图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。

图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。

我们把文件往Git版本库里添加的时候,是分两步执行的:

  • 第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
  • 第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

版本控制

git reset --hard 简洁/完整哈希索引值:回到指定哈希值所对应的版本

git reset --hard HEAD:强制工作区、暂存区、本地库为当前HEAD指针所在的版本

git reset --hard HEAD^:后退一个版本  

  tip:一个^表示回退一个版本

git reset --hard HEAD~1:后退一个版本

  tip:波浪线~后面的数字表示后退几个版本

由上我们可以看出 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
git reset HEAD 命令用于取消已缓存的内容;
当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
假设当前工作目录下有两个文件test.txt、test1.txt现在两个文件修改后,都提交到了缓存区,我们现在要取消其中一个的缓存,操作如下:

$ git status -s
?? test.txt
?? test1.txt
$ git add .
$ git reset HEAD test1.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.

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

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

提交代码

  1. (从现有仓库克隆)仓库clone到本地,修改后再push到远程仓库
#将远程仓库克隆到本地
git clone https://github.com/用户个性地址/PictureBed.git 
git clone git@github.com:TAT123/PictureBed.git

用户也可以通过配置本地的git配置信息,执行git config命令预先配置好相关的用户信息,配置执行如下:

git config --global user.name "你的名字或昵称"
git config --global user.email "你的邮箱"

平台上的提交邮箱与上面配置信息中的邮箱地址保持一致,这样平台就能及时地统计你在平台中提交代码的贡献了。
修改代码后,在仓库目录下执行下面命令:

#将当前目录所有文件添加到git暂存区
git add . 
#提交并备注提交信息
git commit -m "my first commit" 
#将本地提交推送到远程仓库
git push origin master 
  1. (工作目录中初始化新仓库)本地初始化一个仓库,设置远程仓库地址后再做push
    和方法1的差别,在于先创建仓库。
git init 
git remote add origin https://gitee.com/用户个性地址/HelloGitee.git
git pull origin master

新建仓库时,如果在平台仓库上已经存在 readme 或其他文件,在提交时可能会存在冲突,这时用户需要选择的是保留线上的文件或者舍弃线上的文件,如果您舍弃线上的文件,则在推送时选择强制推送,强制推送需要执行下面的命令(默认不推荐该行为):

git push origin master -f

如果您选择保留线上的 readme 文件,则需要先执行:

git pull origin master

分支管理

#创建分支
git branch (branchname)
#切换分支
git checkout (branchname)
#创建并切换到该分支
git checkout -b (branchname)
#列出分支
git branch
#删除分支
git branch -d (branchname)
  • 分支合并 git merge

我们创建了一个分支dev,在该分支的上移除了一些文件 test1.txt,然后切换回我们的主分支,删除的 test1.txt 文件又回来了。

$ git checkout -b dev
Switched to a new branch 'dev'

$ git rm test1.txt
rm 'test1.txt'

$ ls
img/  README.md  test.txt

$ git add .

$ git commit -am 'remove test1.txt'
[dev aeb6d8d] remove test1.txt
 1 file changed, 1 deletion(-)
 delete mode 100644 test1.txt

$ git checkout master

$ ls
img/  README.md  test.txt  test1.txt

使用分支将工作切分开来,从而让我们能够在不同开发环境中做事,并来回切换。我们将 dev 分支合并到主分支去,test.txt 文件被删除。

$ git merge dev
Updating 4f9f7b3..aeb6d8d
Fast-forward
 test1.txt | 1 -
 1 file changed, 1 deletion(-)
 delete mode 100644 test1.txt

git branch
  dev
* master

ls
img/  README.md  test.txt

解决冲突 git merge

# 在本分支合并其他分支
git merge change_site
# 查看冲突
git diff
# 要告诉 Git 
git add

我们创建一个叫做 change_site 的分支,切换过去,我们将 test.txt 内容修改并且提交,切换回master分支我们可以看内容恢复到我们修改前的,我们再次修改 test.txt 文件:

$ git checkout -b change
Switched to a new branch 'change'

$ ls
img/  README.md  test.txt

$ cat test.txt
hello git
$ echo 'test change merge' >> test.txt

$ git commit -am "test merge"

#切换回master
$ git checkout master
Switched to branch 'master'
$ echo 'test master merge' >> test.txt

$ git diff
diff --git a/test.txt b/test.txt
index 8d0e412..4815a4a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1,2 @@
 hello git

$ git commit -am '修改代码'

#查看test.txt的内容
$ cat test.txt
hello git
<<<<<<< HEAD
test master merge
=======
test change merge
>>>>>>> change

#手动修改冲突文件后再提交
git add test.txt
git commit -m 'merge change'

$ cat test.txt
hello git

test master merge

test change merge

更详细的可以查看廖雪峰的网站

仓库管理

本地仓库与远程仓库交互

git clone <远程库地址>:克隆远程库

  功能:①完整的克隆远程库为本地库,②为本地库新建origin别名,③初始化本地库

git remote -v:查看远程库地址别名

git remote add <别名> <远程库地址>:新建远程库地址别名

git remote rm <别名>:删除本地中远程库别名

git push <别名> <分支名>:本地库某个分支推送到远程库,分支必须指定

git pull <别名> <分支名>:把远程库的修改拉取到本地

  tip:该命令包括git fetch,git merge

git fetch <远程库别名> <远程库分支名>:抓取远程库的指定分支到本地,但没有合并

git merge <远程库别名/远程库分支名>:将抓取下来的远程的分支,跟当前所在分支进行合并

git fork:复制远程库

  tip:一般是外面团队的开发人员fork本团队项目,然后进行开发,之后外面团队发起pull request,然后本团队进行审核,如无问题本团队进行merge(合并)到团队自己的远程库,整个流程就是本团队跟外面团队的协同开发流程,Linux的团队开发成员即为这种工作方式。

公钥管理

公钥配置

公钥配置参考

Git配置多个SSH-Key

参考配置多个ssh密钥配置
我的配置:

# 添加config配置文件

# 文件内容如下:
# gitee
Host gitee.com
    HostName gitee.com
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa
	User zfl

# gitlab
Host gitlab.com 
    HostName gitlab.com
    PreferredAuthentications publickey
	Port 60019
    IdentityFile ~/.ssh/id_rsa
	User zfl
# github
Host github.com
    HostName github.com
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/github_id_rsa    
    User zfl
# 配置文件参数
# Host : Host可以看作是一个你要识别的模式,对识别的模式,进行配置对应的的主机名和ssh文件
# HostName : 要登录主机的主机名
# User : 登录名
# IdentityFile : 指明上面User对应的identityFile路径

工作流程

图片名称
多人协作的工作模式通常是这样:
  1. 首先,可以试图用git push origin 推送自己的修改;

  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;

  3. 如果合并有冲突,则使用git diff查看冲突,git status查看冲突文件,解决冲突,并在本地提交;
    没有冲突或者解决掉冲突后,再用git push origin 推送就能成功!

  4. 如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to origin/
    更详细的可以查看廖雪峰的网站

这篇博客是为了给实验室新生培训用的,一些地方讲的也不是很全,日后有机会会完善一下。

posted @ 2020-08-16 18:20  巴山夜雨时☂☂☂  阅读(452)  评论(0编辑  收藏  举报