Git基本操作和Github的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/guanchunsheng/article/details/77160454

本文大部分来自对廖雪峰Git教程 的学习,结合自己的体会,初步掌握Git的使用方法和Github的工作方式。
不会很难,但是琐碎,所以多实践,否则记不住。

1. 版本管理系统

为什么要管理版本,有实际开发经历的人都有体会,就不需要多说了。这就是水和空气一样,那么重要,那么天然。

1.1 集中式

从中央服务器获取文件,修改后送回
这里写图片描述
集中式是比较自然和容易理解的一种方式。大家都从一个服务器下载文档和代码,修改后再送回去,这样就完成了版本控制和多人协作。
早起比较广泛使用的大部分是集中式的版本管理工具:
- CVS
- SVN
- MKS

那么集中式版本管理工具的短板是什么呢。
- 必须联网,否则不能工作
- 性能很差

性能很差这个没有异议,确实很慢,以前在老东家使用MKS作为版本管理工具,性能瓶颈非常恼人。SVN的性能强于MKS,但是仍然不能令人满意。

必须联网这一条并不是说不联网不能修改文件,意思是不联网的话,只能修改本地保存的文件,不能进行版本控制,也就是说如果1天都连不上网,那么这一天的修改都只能一股脑的在下次能联网的时候推上去。

1.2 分布式

每个人的电脑多有一份版本的拷贝,中央服务器不是必须的。
这里写图片描述
分布式与集中式比较起来,我感觉最显著的差别是本地修改的时候可以有自己的版本迭代,并不需要经常的与中央服务器交互。

分布式版本管理工具并不是说完全不用中央服务器。中央服务器可以起到交换各自修改的作用,本地完成修改以后,可以推送到远程服务器上,与其他人协作工作。

分布式版本管理工具比如
- BitKeeper
- Mecurial
- Git

Git太流行,主要的有点是
- 性能好
- 分支管理优秀
这篇文章就是介绍Git的基本用法和一个流行的远程库托管机构Github。

2. Git的安装

2.1 Linux

Linux下是否有安装Git,简单敲一下命令就知道了

git

根据提示信息就知道是否安装了,如果没有安装,我使用的ubuntu,那么apt-get一下就可以:

sudo apt-get install git

2.2 Mac

我没有Mac,所以也没有关注过怎么安装。自行baidu吧。

2.3 Windows

Windows下也是可以安装Git的,安装以后会提供一个Git的shell环境。
Win下的Git软件叫msysgit
这里写图片描述
下载安装即可,用的不多,这里不讨论。

2.4 初次配置

Git使用,需要使用用户名和邮箱作为个人的ID
第一次使用的时候,需要设置一下个人的信息,包括用户名和邮箱,通过命令:

git config --global user.name XXX
git config --global user.email YYY@ZZZ

这里–global 参数表明这是全局的设置,这台电脑上所有的Git仓都会使用这个用户名和邮箱。当然也可以位不同的Git仓使用不同的用户名和邮箱。

3. Git使用

3.1 初始化仓库

Git的文件仓库叫做Repository
在需要建立仓库的文件夹下,输入以下命令建立一个Git仓:

git init

看到提示信息,仓库建立成功。

3.2 添加文件

有了仓库以后,可以向其中添加文件。没有手动添加过的文件,虽然存在与Git仓库文件夹内,也不会受到Git的管理。
添加文件通过以下命令:

git add [file name]
git add *.c
git add .

如果要提交不止一个文件的修改,也是没有问题的,可以反复使用git add,添加多个文件到暂存区,然后一次性的提交到仓库里。或者在一次add中带有多个文件名作为参数,或者通过通配符,“.”等参数添加多个文件进去。

git add 还有其他参数,可以参考:
这里写图片描述

git add只是提交了修改到暂存区,关于暂存区的概念,下边“Git的几个分区”会详细介绍。文件的提交并没有结束,想要真正提交到库上,还需要以下命令

git commit -m "This is a description of the commit"

提交成功后有提示:
这里写图片描述

  • 4个文件有修改
  • 创建了4个文件

3.3 修改文件

3.3.0 Git的几个分区

Git 一共有3个区域的概念
- 工作区 working directory
- 暂存区 stage
- 仓库分支
这里写图片描述
这3个区域,按照层级结构,逐层关联。即工作区和暂存区可以相互影响,暂存区和仓库分支可以相互影响,但是工作区和仓库分支并不能直接相互影响。下文的修改撤销,会对这个问题进行描述。

工作区
工作区就是本地修改文件的工作目录。工作区并不受到Git仓库的管理,可以任意的修改和增删文件。

暂存区
暂存区已经受到Git的管理,所有文件的修改,都需要首先提交到暂存区。前文提到的git add命令,就是将工作区的修改提交到暂存区的命令。

仓库分支
Git的分支比较灵活,可以有一个远程的分支,一般命名位origin,在中央服务器上;本地一个初始的分支,命名为master。本地还可以创建任意多个分支。每次git commit,都是把暂存区的修改,提交到当前的分支上。
关于分支的创建,合并和推送,下文会有说明。

3.3.1查看Git仓库状态

最经常用的一个Git 命令,就是查看当前Git仓库的状态:

git status

看到的结果可能如下
这里写图片描述
这里提示的信息挺全的

  • 有一个文件修改了,1.c
  • 目前可以做的动作有
    • git add 把这个文件的修改添加进暂存区
    • git checkout [file name] 或者 git checkout – [file name] 恢复这个文件,取消修改

现在用git add添加这个文件的修改,再次用git status查看状态
这里写图片描述
提示信息发生了变化,提示到
- git reset HEAD [file] 将暂存区的修改取消,恢复到Git仓中的文件状态
- git commit 提交这个修改到Git仓中,使这个修改在Git仓中生效

3.3.2 查看文件改动

上面的git status只能看到哪个文件被修改了,如果向看具体怎么改的,需要用到另一个命令:

工作区和暂存区的文件比较
git diff [file]

工作区和版本库的文件比较
git diff HEAD [file]

是的,这是Unix标准的diff格式查看命令。
上面改动的1.c文件,已经加入到暂存区中,所以用git diff查看是没有结果的,工作区和暂存区文件一样。应该用git diff HEAD:
这里写图片描述

3.3.3 查看修改记录

想要查看之前提交的各个修改都是什么,需要用到

git log
git log --pretty=oneline
git log --graph

这里写图片描述
其中能够看到的信息是这个提交的id,commit id,提交者,时间,提交的时候 -m 后面双引号括住的提交信息。
commit id是一串哈希值,可以用这个哈希值,或者只是前面若干字符,代表这个commit。
git log的其他参数,可以自己试试。

3.3.4 撤销之前的修改

撤销修改,包括撤销3个区的改动,工作区,暂存区和仓库分支的改动,下面分别说明
所谓修改撤销,就是恢复到上一个已经保存过的文件状态,取消从上一个状态到当前所做的改动。

  • 工作区
    • 工作区的修改,如果想要撤销,只能通过暂存区保存的该文件的上一个状态来恢复。使用的命令是git checkout [file], git checkout – [file]。这个命令执行以后,工作区的文件,就可以恢复到与暂存区一致的状态。
  • 暂存区
    • 暂存区的修改,如果想要撤销,只能通过仓库分支保存的该文件的上一个状态来恢复。使用的命令是git reset HEAD [file]。这个命令执行以后,暂存区的文件,就可以恢复到与仓库分支一致的状态。
  • 仓库分支
    • 仓库分支的修改,如果想要撤销,只能通过再次提交一个修改。暂存区通过git reset HEAD^,可以恢复成仓库分支上一个版本的状态,更多细节参考下文的版本回退。

3.3.5 删除文件

删除文件命令

git rm [file]

注意 本地删除文件,参考git add命令表格,可以通过git add的某些选项和git rm来完成。
这些命令执行以后,文件的删除信息就提交到暂存区了,还需要通过git commit来提交到仓库分支,最终生效。

工作区删除了,但是是误删除,想要恢复怎么办
上一节撤销修改提到,恢复工作区的方法,恢复被删除的文件同样适用。git checkout [file] 即可。

3.4 版本回退

版本的表示
-HEAD
-HEAD^
-HEAD^^
-HEAD~100

这里的版本回退,指的是仓库分支版本的回退。上面的几个版本表示方法,都是仓库分支的版本表示方法。当前版本,前一个,前两个,前100个。

版本回退的命令是

git reset HEAD^
git reset [commit id]
git reset --hard HEAD^
git reset --hard [commit id]

–hard的作用
一并将工作区和暂存区都恢复到目标版本的状态。如果没有这个选项,将只有仓库分支指向的版本发生变化,工作区和暂存区都不动,通过git status能看到版本间的差异。

回退错了,怎么恢复到最新的版本
回退版本之后,git log查看到最新的就是回退之后的版本,更新的版本已经在git log中看不到了。这样就不能通过git reset -hard [commit id]来恢复到之前的新版本。
HEAD也变成了这个稍老一些的版本,不能通过git reset –hard HEAD来恢复。

比如已经进行了几次git commit,版本库增加了几次提交,用git log查看版本库:
这里写图片描述

此时回退版本库,回退到最开始的状态,最后2个提交放弃,那么通过命令:

git log HEAD^^

查看log:
这里写图片描述

可以看到,最后2此提交已经看不到了。那么如果这个时候反悔了,还是想要包括最后的2次提交怎么办呢,在git log里边已经看不到ID号了。还是有办法的,通过以下命令:

git reflog

这里写图片描述
这里边记录了所有的log,可以在这里找到丢失的commit id,通过git reset –hard [commit id]恢复到之前的新版本。

git reset a9af60c

那么就恢复到“update 3.txt”这个版本了。

3.5 分支管理

3.5.0 多分支工作方式

这里写图片描述
Git上多分支的工作方式如图
- 主线master,仅用来发布版本
- dev分支,大家日常工作的分支
- 个人分支,每个人都工作在自己的分支上,阶段性的merge到工作分支dev中
- 个人还可以根据需要,创建更多的分支,修改完成后,merge到个人分支上

3.5.1 创建分支

git checkout -b [branch name]

创建分支,同时切换到这个分支上,相当于2条命令

git branch [branch name]
git checkout [branch name]

3.5.2 查看分支

git branch

查看所有分支的信息,包括有多少个分支,当前处在哪个分支上。

3.5.3 修改分支

切换到哪一个分支,当前就在哪个分支上。
所有的修改,都提交到当前的分支上了。
可以在不同的分支之间随意切换,通过

git checkout [branch]

这里写图片描述
比如上图
- 切换到dev,那么dev的HEAD就是当前的HEAD
- 切换到master,master的HEAD就是当前的HEAD

3.5.4 合并分支

不同的分支用于不同的修改,最终还是需要合并到一起的。
分支合并的方式是
- 切换到主分支(或者相对主分支)
- 通过命令git merge合并

git merge [branch name]

分支合并的FastForward模式
- ff模式,合并进来的分支的HEAD,作为主分支的新的HEAD
- 非ff模式,产生一个新的HEAD,需要参数-m 提供描述信息

ff模式和非ff模式的区别,是在log中能不能看出来曾经有过一个分支。ff模式是看不出来的。
这里写图片描述
所以为了保留完整的log,建议都使用非ff模式合并分支。

git merge --no-ff -m "description" [branch name]

3.5.5 删除分支

合并以后的分支,即可以删除了。
删除分支的命令是

git checkout -d [branch name]

3.5.6 冲突解决

发生冲突的场景一般是,多人共同工作在一个分支上,分别做了各自的修改,然后需要merge到一起。
比如下图
这里写图片描述
图中,feature1分支从master分出来,之后master又merge了别的分支,增长了版本。
那么feature1如何合并入分支master呢。

  1. 在feature1上提交merge
  2. 会提示有冲突,比如下图是一个文本文件,在master上和在feature1上的版本是不同的,图中所示就是这个文件被Git修改标记成了这个样子
    Markdown
  3. 此时需要手动修改这个文件,将最终的修改结果保留到文件中
  4. 再次提交merge,会在master上再增长一个版本
    Markdown

在log中如何查看分支合并信息

git log --graph --pretty=oneline

3.5.7 保护现场

什么是保护现场,为什么要保护现场
从前面的分支操作过程可以看到,任意的切换分支,是可以的。

那么问题来了,切换分支以后,仓库分支是切换了,工作区和暂存区是否随着切换?
- 答案是否定的,工作区和暂存区只有一份,所有的仓库分支共用

如果所有的仓库分支共用一份工作区和暂存区,那么切换到新分支的时候,工作区和暂存区的状态,会影响新的分支,造成混乱。

解决工作区和暂存区在不同分之间共享的方法–保护现场
- 保护现场
- 列出保存过的现场
- 恢复现场

git stash
git stash list
git stash pop

pop以后,该现场就无效了,清理保存过的现场还有其他方式,请自行查看帮助文档

3.5.8 多人协作

前面提到过多人协作的方式。
使用中央服务器作为交换修改的服务器,平时自己工作在本地仓库中,需要时推送修改到远程仓库。

本地仓库是不需要联网的,远程仓库需要联网。

那么远程仓库相关操作:
查看远程仓库信息

git remote
git remote -v

拉取远程仓库的最新状态

git pull

推送本地分支的修改到远程仓库

git push [remote branch] [local branch]

master和dev是需要协同工作的,所以应该部署在远程仓库,作为远程仓库的两个分支
- origin/master
- origin/dev

如果远程有dev分支,那么本地建立对应分支的命令:

git checkout -b dev origin/dev

本地分支,不需要在远程仓库中建立分支

3.6 标签

标签的作用,是给某个特定的版本节点,添加一个可读的名字。否则所有的版本节点都用commit id标识,可读性很差。
比如master上的各个release版本,如果用标签标明,就很容易了解和做相应的处理。

3.6.1 添加

切换到想要添加标签的分支,通过以下命令

git tag [tag name]                              //为当前版本添加标签
git tag [tag name] [commit id]                  //为某个commit id版本添加标签
git tag -a [tag name] -m "tag information"      //添加描述信息
git tag -s [tag name] -m "tag information"      //用PGP签名

3.6.2 查看

查看标签的命令

git tag                     //查看有多少个标签
git show <tag name>         //查看某个标签的说明信息

3.6.3 删除

删除标签的命令

git tag -d [tag name]                   //本地的 
git push origin :refs/tags/[tag name]   //远程的

3.6.4 推送

推送标签到远程的命令

git push origin [tag name]
git push origin --tags

3.7 Git配置

Git的配置一般通过Git配置命令外完成,最主要的有以下几个

  • 颜色
git config --global color.ui true
  • 忽略文件
    • Git工作区根目录下建立文件.gitignore
    • 具体配置方法,见说明
  • 别名
    Markdown
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

/* 配置了这个以后,使用git lg 就可以了,就会使用上述配置来列出log */

Markdown

  • 配置信息作用域
    • 有–global的,用户域有效
    • 没有–global的,仓库域有效
    • 具体反映在不同层级目录的.git/config

3.8 自己搭建Git服务器

  1. 使用ubuntu或者debian系统的电脑
  2. 安装git
  3. 创建一个名位git的用户,运行git服务

    sudo addusr git
  4. 搜集公钥,每行一个写入

    /home/git/.ssh/authorized_keys
  5. 创建裸仓,仓库目录下运行

    sudo git init --bare <repo name>.git
    sudo chown -R git:git sample.git
  6. clone远程仓库

    git clone git@<server>:<path>/<repo name>.git

4. Github

4.1 环境准备

4.1.1 秘钥对

远程仓库登陆和使用需要用户的公钥,用户的签名需要私钥。所以需要生成一对公钥和私钥。
检查以下目录位置,是否已经生成了秘钥对

/*用户目录下 .ssh*/
.ssh/id_rsa         //私钥
.ssh/id_rsa.pub     //公钥 

/*如果没有,通过以下命令生成秘钥对*/
ssh-keygen -t rsa -C "[email protected]"

Github配置

上传公钥
Markdown
可以上传多个公钥,不同的电脑各生成一个,关联到同一个账户

4.2 远程仓库操作

4.2.1 关联

首先在Github上创建新的repository,然后在本地目录下通过下面命令,关联远程仓库到当前文件夹:

git remote add origin git@github.com:[username]/[repository].git

其中[email protected]:xxx,是在github的repository页面找到的地址:
Markdown
origin是远程仓库的分支名称。

4.2.2 clone

如果本地还没有任何相关的文件,那么从远程仓库直接克隆一个到本地比较干净。
通过以下命令:

git clone git@github.com:xxxx/yyyy.git

github地址参考4.2.1节的说明。

4.2.3 推送

推送命令:

git push -u origin master       //第一次,用-u,后续不用
git push origin master          //如果origin下还有分支,用origin/master, origin/dev

第一次推送,会有提示,需要确认以下对端是否可信
Markdown

4.2 仓库间关系

github上,协作的工程有它的原是仓库,参与的人自己fork一份自己的仓库,在自己的仓库上修改。
Markdown

4.1 使用步骤

  1. 找到项目页面
  2. 点fork复制到自己的页面
    Markdown
  3. git clone到本地
  4. 提交修改到自己的github仓库
  5. 提出pull request,发给项目原始页面,建议其包含这个修改

猜你喜欢

转载自blog.csdn.net/guanchunsheng/article/details/77160454