git版本控制工具基本用法讲解(转)

一、安装Git

在linux系统使用非常方便,只需要打开shell界面,并输入:

1
sudo apt-get install git-core

按下回车后输入密码,即可完成Git的安装。但我们可能更多情况下是在windows系统上操作。所以,需要先去官网把git安装包下载下来。 下载后一直下一步完成安装即可。

二、创建代码仓库

首先打开Git Bash配置一下个人身份,这样在提交代码的时候Git 就可以知道是谁提交的了,命令如下

1
2
git config --global user.name "Tony"
git config --global user.email "tony@qq.com"

配置完成后你还可以使用同样的命令来查看是否配置成功,只需要将最后的名字和邮箱地址 去掉即可。

接着我们可以在helloWord项目目录下创建一个代码仓库

1
2
$ cd E:\helloWorld
$ git init        #注释 初始化git仓库

仓库创建完成后,会在helloWord项目的根目录下生成一个隐藏的.git文件夹, 这个文件夹就是用来记录本地所有的Git操作的,可以通过Is -al命令来查看一下。如果你想要删除本地仓库,只需要删除这个文件夹就行了。

三、提交本地代码

1、add 和commit 命令。

add 是用于把想要提交的代码先添加进来,而commit 则是真正地去执行提交操作。

add命令:

添加单个文件

1
git add AndroidManifest.xml

添加单个文件夹

1
git add src

添加所有的文件

1
git add .

commit 命令:

1
git commit -m "First commit."

3、忽略代码

在提交之前,不是所有文件都需要加入到版本控制当中。Git 提供了一种可配性很强的机制来允许用户将指定的文件或目录排除在版本控制之外,它会检查代码仓库的根目录下是否存在一个名为.gitignore 的文件,如果存在的话就去一行行读取这个文件中的内容,并把每一行指定的文件或目录排除在版本控制之外。注意.gitignore 中指定的文件或目录是可以使用“*”通配符的。

1
2
3
/build
*.iml
.gradle

这样就排除掉build目录,.gradle文件,含*.iml的文件

然后就可以直接全部添加了,add命令:

1
git add .

然后执行commit 命令完成提交,如下所示:

1
git commit -m "First commit."

4、查看修改内容

diff 命令,查看文件的更改内容

1
git diff

这样可以查看到所有文件的更改内容,如果你只想查看MainActivity.java 这个文件的更改内容,可以使用如下命令:

1
git diff src/com/example/providertest/MainActivity.java

其中,减号代表删除的部分,加号代表添加的部分。

5、撤销修改内容

如果想要撤销还没有执行过add 命令的文件可以使用checkout 命令,用法如下所示:

1
git checkout src/com/example/providertest/MainActivity.java

执行了这个命令之后,我们对MainActivity.java 这个文件所做的一切修改就应该都被撤销了。

对于已添加的文件我们应该先对其取消添加,然后才可以撤回提交。取消添加使用的是reset 命令,用法如下所示:

1
git reset HEAD src/com/example/providertest/MainActivity.java

然后再运行一遍git status 命令,你就会发现MainActivity.java 这个文件重新变回了未添加状态,此时就可以使用checkout 命令来将修改的内容进行撤销了。

6、查看提交记录

使用log 命令查看历史提交信息,用法如下所示:

1
git log

每次提交记录都会包含提交id、提交人、提交日期,以及提交描述这四个信息。

当提交记录非常多的时候,如果我们只想查看其中一条记录,可以在命令中指定该记录的id,并加上-1 参数表示我们只想看到一行记录,如下所示:

1
git log 2e7c0547af28cc1e9f303a4a1126fddbb704281b -1

而如果想要查看这条提交记录具体修改了什么内容,可以在命令中加入-p 参数,命令如下:

1
git log 2e7c0547af28cc1e9f303a4a1126fddbb704281b -1 –p

其中减号代表删除的部分,加号代表添加的部分。

四、推送到远程

— SSH Key的配置

1、新建SSH Key

1
$ ssh-keygen -t rsa -C "注册邮箱"

提示输入Key名称 注意是完整路径,如C:\Users\Administrator.ssh\irunker。名称和密码不输入,默认会在用户主目录/.ssh下生成两个文件,id_rsa是私钥,id_rsa.pub是公钥。

2、打开.ssh目录的id_rsa.pub文件,复制公钥。

1
$ start ~/.ssh/id_rsa.pub

打开gitub个人空间的ssh keys设置项,Title随便填写 Key添加公钥。

3、测试ssh key是否成功,使用命令“ssh -T git@github.com”,如果出现You’ve successfully authenticated, but GitHub does not provide shell access 。这就表示已成功连上github。

—将本地库同步到远程库:

1.从远程克隆一份到本地可以通过git clone

Git支持HTTPS和SSH协议,SSH速度更快

1
$ git clone git@github.com:visant/**.git

2.本地库关联远程库,在本地仓库目录运行命令:

1
$ git remote add origin git@github.com:visant/**.git

注意要替换为自己仓库的的SSH地址

3.推送master分支的所有内容

1
$ git push -u origin master

第一次使用加上了-u参数,是推送内容并关联分支。

4、推送成功后就可以看到远程和本地的内容一模一样,下次只要本地作了提交,就可以通过命令:

1
$ git push origin master

其中origin 部分指定的是远程版本库的Git 地址,master 部分指定的是同步到哪一个分支上,上述命令就完成了将本地代码同步到~/**.git这个版本库的master 分支上的功能。

—将远程库同步到本地库

1、Git 提供了两种命令来完成此功能,分别是fetch 和pull,fetch 的语法规则和push 是差不多的,如下所示:

1
git fetch origin master

执行这个命令后,就会将远程版本库上的代码同步到本地,不过同步下来的代码并不会合并到任何分支上去,而是会存放在到一个origin/master 分支上。

2、这时可以通过diff 命令来查看远程版本库上到底修改了哪些东西:

1
git diff origin/master

3、之后再调用merge 命令将origin/master 分支上的修改合并到主分支上即可,如下所示:

1
git merge origin/master

4、而pull 命令则是相当于将fetch 和merge 这两个命令放在一起执行了,它可以从远程版本库上获取最新的代码并且合并到本地,用法如下所示:

1
git pull origin master

五、分支的用法

分支是版本控制工具中比较高级且比较重要的一个概念,它主要的作用就是在现有代码的基础上开辟一个分叉口,使得代码可以在主干线和分支线上同时进行开发,且相互之间不会影响。

1、查看当前的版本库当中的分支,命令如下:

1
git branch –a

2、创建一个分支(version1.0),命令如下:

1
git branch version1.0

3、切换到某一个分支,命令如下:

1
git checkout version1.0

4、删除某一个分支,命令如下:

1
git branch -d version1.0

5、分支和主干是互不影响的,如果要将分支合并到主干线上,使用如下命令:

1
2
git checkout master  #切换到主干线上
git merge version1.0

六、测试使用

1、克隆git仓库项目并创建新文件

1
2
3
4
$ git clone https://github.com/Jrohy/MyWeather.git
$ cd MyWeather/
$ touch a.txt b.txt
$ ls

2、添加文件到缓存

1
2
3
4
$ git status -s 
# 注释:以精简的方式显示文件状态 有三种状态:A AM M
# A:新文件第一次被添加进版本管理
# M:红色为修改过未被添加进暂存区的,绿色为修改过已经添加进暂存区的
1
2
3
4
5
6
7
8
9
10
11
12
# 添加个别文件到缓存
$ git add a.txt b.txt
$ git status -s  #显示文件状态
$ vim a.txt #vi命令 如 a字符后插入 i字符前插入 :w保存 :q退出 :wq保存退出
$ vim README.md
$ git status -s  #文件状态M为红色;
# 添加所有文件夹到缓存
$ git add .
$ git status -s  #文件状态M为绿色
# 移除缓存区的文件
$ git reset HEAD a.txt  #回退文件,将文件从暂存区回退到工作区
$ git rm --cached a.txt #和git reset作用一样

3、提交文件到本地仓库

1
2
3
$ git commit -m "第一次提交"
$ vim a.txt
$ git commit -am "第二次提交"   # -a跳过添加缓存 直接提交

4、同步到gitub远程仓库

1
2
3
$ git remote add origin git@github.com:geek/Test.git  #添加一个远程仓库
$ git push origin master  #提示输入用户名和密码来进行身份校验               
---如果提示error: src refspec master does not match any. 是因为缓存区没内容

七、常用命令

git init

在本地新建一个repo,进入一个项目目录,执行git init,会初始化一个repo,并在当前文件夹下创建一个.git文件夹.

git clone

获取一个url对应的远程Git repo, 创建一个local copy.

一般的格式是git clone [url].

clone下来的repo会以url最后一个斜线后面的名称命名,创建一个文件夹,如果想要指定特定的名称,可以git clone [url] newname指定.

git status

查询repo的状态.

git status -s: -s表示short, -s的输出标记会有两列,第一列是对staging区域而言,第二列是对working目录而言.

git log

show commit history of a branch.

git log –oneline –number: 每条log只显示一行,显示number条.

git log –oneline –graph:可以图形化地表示出分支合并历史.

git log branchname可以显示特定分支的log.

git log –oneline branch1 ^branch2,可以查看在分支1,却不在分支2中的提交.^表示排除这个分支(Window下可能要给^branch2加上引号).

git log –decorate会显示出tag信息.

git log –author=[author name] 可以指定作者的提交历史.

git log –since –before –until –after 根据提交时间筛选log.

–no-merges可以将merge的commits排除在外.

git log –grep 根据commit信息过滤log: git log –grep=keywords

默认情况下, git log –grep –author是OR的关系,即满足一条即被返回,如果你想让它们是AND的关系,可以加上–all-match的option.

git log -S: filter by introduced diff.

比如: git log -SmethodName (注意S和后面的词之间没有等号分隔).

git log -p: show patch introduced at each commit.

每一个提交都是一个快照(snapshot),Git会把每次提交的diff计算出来,作为一个patch显示给你看.

另一种方法是git show [SHA].

git log –stat: show diffstat of changes introduced at each commit.

同样是用来看改动的相对信息的,–stat比-p的输出更简单一些.

git add

在提交之前,Git有一个暂存区(staging area),可以放入新添加的文件或者加入新的改动. commit时提交的改动是上一次加入到staging area中的改动,而不是我们disk上的改动.

git add .

会递归地添加当前工作目录中的所有文件.

git diff

不加参数的git diff:

show diff of unstaged changes.

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

若要看已经暂存起来的文件和上次提交时的快照之间的差异,可以用:

git diff –cached 命令.

show diff of staged changes.

(Git 1.6.1 及更高版本还允许使用 git diff –staged,效果是相同的).

git diff HEAD

show diff of all staged or unstated changes.

也即比较woking directory和上次提交之间所有的改动.

如果想看自从某个版本之后都改动了什么,可以用:

git diff [version tag]

跟log命令一样,diff也可以加上–stat参数来简化输出.

git diff [branchA] [branchB]可以用来比较两个分支. 它实际上会返回一个由A到B的patch,不是我们想要的结果.

一般我们想要的结果是两个分支分开以后各自的改动都是什么,是由命令:

git diff [branchA]…[branchB]给出的.

实际上它是:git diff $(git merge-base [branchA] [branchB]) [branchB]的结果.

git commit

提交已经被add进来的改动.

git commit -m “the commit message”

git commit -a 会先把所有已经track的文件的改动add进来,然后提交(有点像svn的一次提交,不用先暂存). 对于没有track的文件,还是需要git add一下.

git commit –amend 增补提交. 会使用与当前提交节点相同的父节点进行一次新的提交,旧的提交将会被取消.

git reset

undo changes and commits.

这里的HEAD关键字指的是当前分支最末梢最新的一个提交.也就是版本库中该分支上的最新版本.

git reset HEAD: unstage files from index and reset pointer to HEAD

这个命令用来把不小心add进去的文件从staged状态取出来,可以单独针对某一个文件操作: git reset HEAD - - filename, 这个- - 也可以不加.

git reset –soft

move HEAD to specific commit reference, index and staging are untouched.

git reset –hard

unstage files AND undo any changes in the working directory since last commit.

使用git reset —hard HEAD进行reset,即上次提交之后,所有staged的改动和工作目录的改动都会消失,还原到上次提交的状态.

这里的HEAD可以被写成任何一次提交的SHA-1.

不带soft和hard参数的git reset,实际上带的是默认参数mixed.

总结:

git reset –mixed id,是将git的HEAD变了(也就是提交记录变了),但文件并没有改变,(也就是working tree并没有改变). 取消了commit和add的内容.

git reset –soft id. 实际上,是git reset –mixed id 后,又做了一次git add.即取消了commit的内容.

git reset –hard id.是将git的HEAD变了,文件也变了.

按改动范围排序如下:

soft (commit) < mixed (commit + add) < hard (commit + add + local working)

git revert

反转撤销提交.只要把出错的提交(commit)的名字(reference)作为参数传给命令就可以了.

git revert HEAD: 撤销最近的一个提交.

git revert会创建一个反向的新提交,可以通过参数-n来告诉Git先不要提交.

git rm

git rm file: 从staging区移除文件,同时也移除出工作目录.

git rm –cached: 从staging区移除文件,但留在工作目录中.

git rm –cached从功能上等同于git reset HEAD,清除了缓存区,但不动工作目录树.

git clean

git clean是从工作目录中移除没有track的文件.

通常的参数是git clean -df:

-d表示同时移除目录,-f表示force,因为在git的配置文件中, clean.requireForce=true,如果不加-f,clean将会拒绝执行.

git mv

git rm - - cached orig; mv orig new; git add new

git stash

把当前的改动压入一个栈.

git stash将会把当前目录和index中的所有改动(但不包括未track的文件)压入一个栈,然后留给你一个clean的工作状态,即处于上一次最新提交处.

git stash list会显示这个栈的list.

git stash apply:取出stash中的上一个项目(stash@{0}),并且应用于当前的工作目录.

也可以指定别的项目,比如git stash apply stash@{1}.

如果你在应用stash中项目的同时想要删除它,可以用git stash pop

删除stash中的项目:

git stash drop: 删除上一个,也可指定参数删除指定的一个项目.

git stash clear: 删除所有项目.

git branch

git branch可以用来列出分支,创建分支和删除分支.

git branch -v可以看见每一个分支的最后一次提交.

git branch: 列出本地所有分支,当前分支会被星号标示出.

git branch (branchname): 创建一个新的分支(当你用这种方式创建分支的时候,分支是基于你的上一次提交建立的).

git branch -d (branchname): 删除一个分支.

删除remote的分支:

git push (remote-name) :(branch-name): delete a remote branch.

这个是因为完整的命令形式是:

git push remote-name local-branch:remote-branch

而这里local-branch的部分为空,就意味着删除了remote-branch

git checkout

git checkout (branchname) 切换到一个分支.

git checkout -b (branchname): 创建并切换到新的分支.

这个命令是将git branch newbranch和git checkout newbranch合在一起的结果.

checkout还有另一个作用:替换本地改动:

git checkout –

此命令会使用HEAD中的最新内容替换掉你的工作目录中的文件.已添加到暂存区的改动以及新文件都不会受到影响.

注意:git checkout filename会删除该文件中所有没有暂存和提交的改动,这个操作是不可逆的.

git merge

把一个分支merge进当前的分支.

git merge [alias]/[branch]

把远程分支merge到当前分支.

如果出现冲突,需要手动修改,可以用git mergetool.

解决冲突的时候可以用到git diff,解决完之后用git add添加,即表示冲突已经被resolved.

git tag

tag a point in history as import.

会在一个提交上建立永久性的书签,通常是发布一个release版本或者ship了什么东西之后加tag.

比如: git tag v1.0

git tag -a v1.0, -a参数会允许你添加一些信息,即make an annotated tag.

当你运行git tag -a命令的时候,Git会打开一个编辑器让你输入tag信息.

我们可以利用commit SHA来给一个过去的提交打tag:

git tag -a v0.9 XXXX

push的时候,是不包含tag的,如果想包含,可以在push时加上–tags参数.

fetch的时候,branch HEAD可以reach的tags是自动被fetch下来的, tags that aren’t reachable from branch heads will be skipped.如果想确保所有的tags都被包含进来,需要加上–tags选项.

git remote

list, add and delete remote repository aliases.

因为不需要每次都用完整的url,所以Git为每一个remote repo的url都建立一个别名,然后用git remote来管理这个list.

git remote: 列出remote aliases.

如果你clone一个project,Git会自动将原来的url添加进来,别名就叫做:origin.

git remote -v:可以看见每一个别名对应的实际url.

git remote add [alias] [url]: 添加一个新的remote repo.

git remote rm [alias]: 删除一个存在的remote alias.

git remote rename [old-alias] [new-alias]: 重命名.

git remote set-url [alias] [url]:更新url. 可以加上—push和fetch参数,为同一个别名set不同的存取地址.

git fetch

download new branches and data from a remote repository.

可以git fetch [alias]取某一个远程repo,也可以git fetch –all取到全部repo

fetch将会取到所有你本地没有的数据,所有取下来的分支可以被叫做remote branches,它们和本地分支一样(可以看diff,log等,也可以merge到其他分支),但是Git不允许你checkout到它们.

git pull

fetch from a remote repo and try to merge into the current branch.

pull == fetch + merge FETCH_HEAD

git pull会首先执行git fetch,然后执行git merge,把取来的分支的head merge到当前分支.这个merge操作会产生一个新的commit.

如果使用–rebase参数,它会执行git rebase来取代原来的git merge.

git rebase

–rebase不会产生合并的提交,它会将本地的所有提交临时保存为补丁(patch),放在”.git/rebase”目录中,然后将当前分支更新到最新的分支尖端,最后把保存的补丁应用到分支上.

rebase的过程中,也许会出现冲突,Git会停止rebase并让你解决冲突,在解决完冲突之后,用git add去更新这些内容,然后无需执行commit,只需要:

git rebase –continue就会继续打余下的补丁.

git rebase –abort将会终止rebase,当前分支将会回到rebase之前的状态.

git push

push your new branches and data to a remote repository.

git push [alias] [branch]

将会把当前分支merge到alias上的[branch]分支.如果分支已经存在,将会更新,如果不存在,将会添加这个分支.

如果有多个人向同一个remote repo push代码, Git会首先在你试图push的分支上运行git log,检查它的历史中是否能看到server上的branch现在的tip,如果本地历史中不能看到server的tip,说明本地的代码不是最新的,Git会拒绝你的push,让你先fetch,merge,之后再push,这样就保证了所有人的改动都会被考虑进来.

git reflog

git reflog是对reflog进行管理的命令,reflog是git用来记录引用变化的一种机制,比如记录分支的变化或者是HEAD引用的变化.

当git reflog不指定引用的时候,默认列出HEAD的reflog.

HEAD@{0}代表HEAD当前的值,HEAD@{3}代表HEAD在3次变化之前的值.

git会将变化记录到HEAD对应的reflog文件中,其路径为.git/logs/HEAD, 分支的reflog文件都放在.git/logs/refs目录下的子目录中.

特殊符号:

^代表父提交,当一个提交有多个父提交时,可以通过在^后面跟上一个数字,表示第几个父提交: ^相当于^1

~相当于连续的个^

 

参考资料   https://www.2cto.com/kf/201711/701766.html

posted @ 2018-10-19 16:38  pyng  阅读(939)  评论(0编辑  收藏  举报