GIT命令操作

git命令的使用整理

https://www.liaoxuefeng.com/wiki/896043488029600/896954074659008

1.首先,安装git

windows
  • 下载git安装包
  • 安装完成后,在命令行中设置
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"

因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。

注意git config命令的–global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

2.使用GIT创建版本库

  • 首先,选择一个合适的地方,创建一个空目录:
  • git init 命令把这个目录变成Git可以管理的仓库:

3.使用GIT提交

  • git add 选择本次需要commit的文件,提交到暂存区state
  • git commit 把所有add的文件提交到仓库(当前分支)
$ git commit -m "wrote a readme file"
[master (root-commit) eaadf4e] wrote a readme file
 1 file changed, 2 insertions(+)
 create mode 100644 readme.txt

4.git回滚版本状态

  • git status | 查看仓库当前的状态,看看有没有文件呗改动
  • git diff | 查看文件修改记录|
git diff readme.txt 
  • git log 显示最近到最远提交的日志,查看有几次提交
git log --pretty=oneline 美观显示
  • git reset --hard HEAD^ 还原到上过版本(用于撤销git add之后暂存区的更改)
  • git diff HEAD– readme.txt 查看工作区和版本库里面最新版本的区别:
$ git diff HEAD -- readme.txt 
diff --git a/readme.txt b/readme.txt
index 76d770f..a9c5755 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,4 +1,4 @@
 Git is a distributed version control system.
 Git is free software distributed under the GPL.
 Git has a mutable index called stage.
-Git tracks changes.
+Git tracks changes of files.

首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交1094adb…(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD,上上一个版本就是HEAD,当然往上100个版本写100个比较容易数不过来,所以写成HEAD~100。

  • git reset --hard 1094a 指定还原到某个版本,可以是过去的,也可以是未来的

1094a 代表git log中的某一次的commit id

  • git reflog 用来记录你的每一次命令,可以查看到每次提交的commit id用于回退操作
$ git refloge475afc HEAD@{1}: reset: moving to HEAD^
1094adb (HEAD -> master) HEAD@{2}: commit: append GPLe475afc HEAD@{3}: commit: add distributedeaadf4e HEAD@{4}: commit (initial): wrote a readme file
命令 解释 示例
git status 查看仓库当前的状态,看看有没有文件呗改动
git diff 查看文件修改记录 git diff readme.txt

5.git撤销工作区的修改

  • 工作区:指你手上正在编辑的区域
  • 暂存区(state):指你本地使用git add命令后提交到的区域
  • 版本库:指的是你使用git commit命令提交后的区域

  • git checkout - - file 可以丢弃工作区的修改(针对于没有add的情况下,只修改了工作区的内容)

命令git checkout – readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次git commit或git add时的状态。

注:git checkout – file命令中的–很重要,没有–,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout命令。

很重要的一点,关于删除文件,如果是工作区内误删,但没有提交,也可以使用这个命令找回文件:

git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

注意:从来没有被添加到版本库就被删除的文件,是无法恢复的!
  • git reset HEAD < file > 暂存区的修改撤销掉(unstage)

针对于,不仅修改了工作区的内容,还使用了add命令将其放入了暂存区,但庆幸的是没有提交

  • 如果已经Commit过了,参考上面的版本回退,不过前提是没有推送到远程库。

总结

  • git reset 针对git add之后的暂存区
    git reset HEAD < file > 暂存区的修改撤销掉(unstage)
    git reset --hard HEAD^ 还原到上个版本
    git reset --hard 1094a 指定还原到某个版本
  • git checkout 针对工作区修改之后,没有git add的情况
    git checkout – * 是撤销从上次提交之后所做的所有修改
    git checkout – filaname 是撤销从上次提交之后的单个文件的修改
删除 一些 没有 git add 的 文件;

git clean 参数

    -n 显示 将要 删除的 文件 和  目录

     -f 删除 文件,-df 删除 文件 和 目录

git clean -n

git clean -df

git clean -f

参考 https://blog.csdn.net/kikajack/article/details/79846098

  • 远程仓库的回滚

参考 https://cnblogs.com/Super-scarlett/p/8183348.html

6.使用GitHub将本地库连接到远程仓库

  • 创建SSH key
$ ssh-keygen -t rsa -C "[email protected]"
  • 添加SSH

登陆GitHub,打开“Account settings”,“SSH Keys”页面:

然后,点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容:

GIT命令操作_第1张图片

  • 创建GITHUB远程仓库

https://www.liaoxuefeng.com/wiki/896043488029600/898732864121440

  • 关联远程仓库

要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git

git branch --set-upstream-to=origin/develop develop

将本地的develop分支与远程的相关联

$ git remote add origin git@github.com:michaelliao/learngit.git
  • 第一次推送master

关联后,使用命令git push -u origin master第一次推送master分支的所有内容;

  • 而后推送master

此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;

7.从GitHub远程库克隆

  • 创建远程仓库
  • git clone 操作克隆库
git clone git@github.com:michaelliao/gitskills.git
你也许还注意到,GitHub给出的地址不止一个,还可以用https://github.com/michaelliao/gitskills.git这样的地址。实际上,Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。

使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https。

要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。

Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。
https://blog.csdn.net/ypbsyy/article/details/80546796

8.Git使用分支

https://www.liaoxuefeng.com/wiki/896043488029600/900003767775424

  • git chekout -b dev 创建并切换到该分支
$ git checkout -b dev
Switched to a new branch 'dev'

git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:

$ git branch dev
$ git checkout dev
Switched to branch 'dev'
  • git branch 查看当前分支

git branch命令会列出所有分支,当前分支前面会标一个*号。

  • git merge 用于分支合并

git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。

$ git merge dev # 合并dev分支到当前的master分支
  • git branch -d dev 删除dev分支
$ git branch -d dev
Deleted branch dev (was b17d20e).
小结
Git鼓励大量使用分支:

查看分支:git branch

创建分支:git branch <name>

切换分支:git checkout <name>

创建+切换分支:git checkout -b <name>

合并某分支到当前分支:git merge <name>

删除分支:git branch -d <name>

8.Git解决冲突

当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。

解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。

git log --graph命令可以看到分支合并图。
用Q推出 git log

9.禁用Fast forward模式合并分支

git merge --no-ff -m "merge with no-ff" dev

通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。

如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
准备合并dev分支,请注意–no-ff参数,表示禁用Fast forward:
因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。

合并分支时,加上–no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。

10.bug分支管理

https://www.liaoxuefeng.com/wiki/896043488029600/900388704535136

  • 当本地的内容(dev)分支不想提交,但是(master)分支又有BUG需要解决时
  1. 将本地的内容,假设是(dev)分支上的,add暂存,
  2. 使用git stash 命令,改命令会将state暂存区的内容贮藏起来
  3. 注意:创建新分支时,会默认从最新的commit的版本库中创建
  4. 切换到master,创建新的Bug分支,假设为issue101,在这个分支上修复BUG
  5. 回到master分支(或者别的分支,回到哪个分支取决于你是要在哪个分支上解决BUG),然后合并issue101到这个分支
  6. 回到dev分支,使用git stash apply stash@{0} 恢复指定贮藏,或者使用git stash pop恢复最新的贮藏,二者的不同是pop会在恢复后删除贮藏
  7. 删除issue-101分支
  8. 在dev分支上继续干活
  • git stash apply 恢复储藏,但是恢复后,stash内容并不删除
$ git stash apply stash@{0}  # 恢复指定的储藏
  • git stash drop 删除贮藏
  • git stash pop 恢复储藏的同时把stash内容也删了
  • git stash list 查看储藏

11.feature 分支

  • 当需要开发一个新功能(比如要添加新文件时),需要新开辟一个分支在上面开发,开发结束后合并

注:开发一个新feature,最好新建一个分支;

如果要丢弃一个没有被合并过的分支,可以通过git branch -D 强行删除。

$ git branch -D feature-vulcan
Deleted branch feature-vulcan (was 287773e).

12.多人协作

  • git remote 查看远程仓库信息
  • git remote -v 显示更详细的信息:

  • git push 向远程仓库推送分支
$ git push origin master  # 向远程仓库origin推送本地master分支
$ git push origin dev #向远程仓库origin推送本地dev分支

但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?

  1. master分支是主分支,因此要时刻与远程同步;

  2. dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;

  3. bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;

  4. feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发

抓取分支 git pull

https://www.liaoxuefeng.com/wiki/896043488029600/900375748016320

  • git branch --set-upstream-to=origin/dev dev 指定本地dev分支与远程origin/dev分支的链接
总结

因此,多人协作的工作模式通常是这样:

首先,可以试图用git push origin 推送自己的修改;

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

如果合并有冲突,则解决冲突,并在本地提交;

没有冲突或者解决掉冲突后,再用git push origin 推送就能成功!

如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to origin/。

这就是多人协作的工作模式,一旦熟悉了,就非常简单。

小结

查看远程库信息,使用git remote -v;

本地新建的分支如果不推送到远程,对其他人就是不可见的;

从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;

在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;

建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name;

从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。

13.git rebase整理分支提交

https://www.liaoxuefeng.com/wiki/896043488029600/1216289527823648

rebase操作可以把本地未push的分叉提交历史整理成直线

rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。

注意,使用rebase的场景是在pull完之后还没有push本地的内容

rebase 之前

$ git log --graph --pretty=oneline --abbrev-commit
*   e0ea545 (HEAD -> master) Merge branch 'master' of github.com:michaelliao/learngit
|\  
| * f005ed4 (origin/master) set exit=1
* | 582d922 add author
* | 8875536 add comment
|/  
* d1be385 init hello

rebase 之后

$ git log --graph --pretty=oneline --abbrev-commit
* 7e61ed4 (HEAD -> master) add author
* 3611cfe add comment
* f005ed4 (origin/master) set exit=1
* d1be385 init hello

他将pull下来的f005ed4当成了本地的一次提交,放在了我还没有push的两条内容之后,因此,我们本地的commit修改内容已经变化了,它们的修改不再基于d1be385 init hello,而是基于f005ed4 (origin/master) set exit=1,但最后的提交7e61ed4内容是一致的。

使用push推送之后

$ git log --graph --pretty=oneline --abbrev-commit
* 7e61ed4 (HEAD -> master, origin/master) add author
* 3611cfe add comment
* f005ed4 set exit=1
* d1be385 init hello

14.标签管理

https://www.liaoxuefeng.com/wiki/896043488029600/900788941487552

tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。其实它就是指向某个commit的指针(跟分支很像对不对?但是分支可以移动,标签不能移动),所以,创建和删除标签都是瞬间完成的。

创建标签
  1. 切换到要打标签的分支
  2. git tag 打一个新标签(这个标签默认是打在最新提交的commit上面的)
$ git tag v1.0
  1. git tag 查看所有标签
对指定的commit打标签
  • git log --pretty=oneline --abbrev-commit 列出历史提交的commit Id
  • git tag v0.9 f52c633 对指定的commit打标签

补充
  • git show 查看标签信息
$ git show v0.9
commit f52c63349bc3c1593499807e5c8e972b82c8f286 (tag: v0.9)
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 21:56:54 2018 +0800

    add merge

diff --git a/readme.txt b/readme.txt
  • 创建带有说明的标签

git tag -a v0.1 -m “version 0.1 released” 1094adb

用-a指定标签名,-m指定说明文字

** 注意:标签总是和某个commit挂钩。如果这个commit既出现在master分支,又出现在dev分支,那么在这两个分支上都可以看到这个标签。**

小结
命令git tag <tagname>用于新建一个标签,默认为HEAD,也可以指定一个commit id;

命令git tag -a <tagname> -m "blablabla..."可以指定标签信息;

命令git tag可以查看所有标签。

git tag -d v0.1 删除标签
git push origin 将标签推送到远程
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
 * [new tag]         v1.0 -> v1.0
git push origin --tags 一次性推送全部尚未推送到远程的本地标签
如果已经push了标签到远程
  • git tag -d v0.9 先删除本地标签
  • git push origin :refs/tags/v0.9 删除远程标签
小结
命令git push origin <tagname>可以推送一个本地标签;

命令git push origin --tags可以推送全部未推送过的本地标签;

命令git tag -d <tagname>可以删除一个本地标签;

命令git push origin :refs/tags/<tagname>可以删除一个远程标签。
提问:GitHub中让别人接受你fork后修改的代码为什么要叫pull request而不叫push request?

https://segmentfault.com/q/1010000009850353/a-1020000009850473/revision

pull request的理解方法是:一个通知上游repo所有者拉取代码(pull)的请求(request)。

在英语中,request一般指的是提交一个申请,需要对方对申请给予答复的。而request之前的修饰词,则是答复方的动作,当然,中文中也是一样。比如“入团申请”,你提交申请之后,需要对方允许你入团你才算是团员。所以,入团的动作不是你主动做的,而是由审核的人把你的名字加上去才算“入团”。同理“pull request”中,request是你提交的,而pull则是对方做的事情。

我的总结:至于pull还是push是对最终动作的决定者而言的,而不是对动作的发起者而言的。

15.配置git

15.1忽略特殊文件

https://www.liaoxuefeng.com/wiki/896043488029600/900004590234208

  1. 在Git工作区的根目录下创建一个特殊的 .gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
  2. 最后一步就是把 .gitignore 也提交到Git

忽略文件的原则是

忽略操作系统自动生成的文件,比如缩略图等;

忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;

忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。

检验.gitignore的标准是git status命令是不是说working directory clean。

  • git add -f App.class 强制上传被忽略的文件
  • git check-ignore 检查被忽略的文件

15.2 给命令配置别名
  • 设置git status 为git st
git config --global alias.st status

注意:配置Git的时候,加上–global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。

配置文件放哪了?每个仓库的Git配置文件都放在.git/config文件中:

你可能感兴趣的:(git,Git命令)