Git学习笔记

SVN、CVS都是集中式的版本控制系统。集中式版本控制系统,版本库是集中放在中央服务器,工作的时候用的是自己的电脑,所以要先从中央服务器取得最新的版本来工作,完成后,再推送到中央服务器。最大毛病就是必须联网才能工作。

Git是分布式版本控制系统。分布式版本控制系统没有中央服务器,每个人的电脑上都有一个完整的版本库,那么工作时就不需要联网了。各自的修改通过推送的方式通知给对方。

两者最大不同是,使用git,在没有网络的情况下,你可以提交给本地,在本地做版本管理的所有处理。比如提交版本1,提交版本2,提交3,然后恢复版本1,开一个分支,切换分支,修改代码,合并分支。这和集中式的svn非常不同,svn你离线时可以提交吗?绝对不能。git则可以在无网络情况下本地提交,他把提交版本与推送服务器这两个概念分开了。而svn之流是融为一体的,提交即推送给服务器。因此,git是去中心的,他的服务器并非必须的,只是为了方便大家交流使用,你完全可以把git服务器想象成一个参与者,他得电脑始终在线,他不写代码,只接受大家的推送与合并,然后供其他用户从他这里拉取信息。

完成安装后,要对git进行设置

$ git config –global user.name “Your Name”

$ git config –global user.email “email@example.com”

以上指令会使这台机器上的所有Git仓库都使用这个设置,也可以对不同仓库是同不同设置。

一、Git命令

1.创建目录

$ mkdir directoryName

2.初始化新的repository

$ git init

初始化完成后可用$ ls查看当下目录下文件;
$ ls -ah可以查看到隐藏文件,包括.git等。.git目录是用来跟踪管理版本库的,不能随便修改。

3.将远程仓库拷贝至本地

生成一个与远程主机的版本库同名的目录

$ git clone <http://… 即url>

git clone支持多种协议,除了HTTP(s)以外,还支持SSH、Git、本地文件协议等。

$ git clone http[s]://example.com/path/to/repo.git/

$ git clone ssh://example.com/path/to/repo.git/

$ git clone git://example.com/path/to/repo.git/

$ git clone /opt/git/project.git

$ git clone file:///opt/git/project.git

$ git clone ftp[s]://example.com/path/to/repo.git/

$ git clone rsync://example.com/path/to/repo.git/

SSH协议还有另一种写法:

$ git clone [user@]example.com:path/to/repo.git/

Git协议下载速度最快,SSH协议用于需要用户认证的场合。

如果要指定不同的目录名,可以将第二个目录名作为git clone命令的第二个参数

$ git clone <url> <本地目录名>

4.添加修改

添加所有修改

$ git add *

添加修改文件XX

$ git add XX

5.查看本地仓库状态

$ git status

6.查看修改内容

工作区和暂存区的比较

$ git diff

暂存区和当前分支的比较

$ git diff —cached

7.提交

输入一行提交信息

$ git commit -m “”

输入多行提交信息

$ git commit -m ‘lots of
commit message’

8.查看git日志

8.1 git log

图形化展现分支合并历史记录

$ git log –graph –oneline –decorate

$ git log –graph –pretty=oneline

$ git log –graph –pretty=oneline –abbrev-commit

列表模式展现,较git log输出相对较少,除去了部分信息,查看更清晰

$ git log –pretty=oneline

8.2 git shortlog

shortlog 是特殊版本的git log,将commit按照作者分组,显示每个commit的第一行描述,很方便看到其他人的操作。
默认情况下按照作者名排序,可以使用-n按照每个作者的commit数量排序。

8.3 其他修饰词

oneline : 标记将每个commit压缩成一行,默认情况下显示一个commit ID和commit描述的第一行
decorate :知道commit的哪个分支或者tag关联是十分有用的,decorate标记会让git log显示每个commit的引用(如:分支、tag等),可以结合其他的config选项使用。
stat :显示每个commit中每个文件添加的行数和删除的行数,这对了解一个commit大致有什么修改非常有用。
-p :可以看commit具体修改了什么(是stat的详细版)。

graph :会画出一个ASCII图展示commit历史的分支结构,通常和–oneline和–decorate一起用。*说明commit在哪个branch上。

pretty=format:”<string>” :自定义输出。 —>>>例如%cn代表commiter name,%h表示commit hash的缩写,%cd表示commite date。

$ git log --pretty=format:”%cn committed %h on %cd”  
 git committed 9dbd3bc on Mon Jan 9 15:12:58 2017 +0800  
 git committed 6388117 on Mon Jan 9 09:44:14 2017 +0800  
 git committed 3e74a7a on Fri Jan 6 17:59:53 2017 +0800  

-n 限制输出的数量

$ git log -n  //-n
$ git log -3 —oneline  //只输出3个  
 9dbd3bc cherry-pic again   
 9942412 cherry-pick in branch dev  
 6388117 set upstream to  .---- dev branch  

after或–before 来按照日期筛选。还可以使用相对的时间,例如“1 week ago”和“yesterday”。
如果看某个时间段,可以同时使用两个。
since和–until

$ git log --after "2017-1-8” --oneline
 23a3371 revert tag   
 9dbd3bc cherry-pic again   
 9942412 cherry-pick in branch dev   
 6388117 set upstream to  .---- dev branch   
$ git log --before “yesterday” --oneline
 23a3371 revert tag   
 9dbd3bc cherry-pic again   
 9942412 cherry-pick in branch dev   
 6388117 set upstream to  .---- dev branch   
 3e74a7a merge bug fixed in issue1   
 1e628db fix issue in issue1   
 47e0f91 fix bug - 101   
 54727cc ----------merge with no-ff   
 0a95587 new merge -- --no-off   
 fb41a26 add merge -- new dev   
 5c102fd conflict fixed -- in master   
 24cbab1 & simple ---- master   
 773006b And Simple ---- featural   
 02b2f2d branch test   
 e00a40c branch test   
 8be51a1 append GPL   
 df7c2de initial repository  

author作者。作者名不需要精确匹配,包含即可。还可以使用正则表达式。这里–author不仅包含名还包含email。

$ git log --author=“gi”   // $ git log --author=“john\|mary" 
$ git log --author="gi" --oneline
 9dbd3bc cherry-pic again   
 9942412 cherry-pick in branch dev   
 6388117 set upstream to  .---- dev branch   
 3e74a7a merge bug fixed in issue1   
 1e628db fix issue in issue1   
 47e0f91 fix bug - 101   
 54727cc ----------merge with no-ff

grepcommit描述,如果团队会在commit描述里面加上相关的issue号。通过issue来查找相关的commit,还可以传入-i来忽略大小写。

$ git log --grep="dev" --oneline 
  9942412 cherry-pick in branch dev  
  6388117 set upstream to  .---- dev branch   
  fb41a26 add merge -- new dev   
$ git log --grep="test" --oneline
  02b2f2d branch test   
  e00a40c branch test   

–按文件,键入相应文件路径即可,这里的–是告诉Git后面的参数是文件路径而不是branch的名字,若路径和branch不会混淆,可省略–

$ git log -- readme.txt
 commit 9dbd3bce4d0e1fb446e8c4b72f5ed81c7f4a7b2f  
 Author: git &lt;XX>  
 Date:   Mon Jan 9 15:12:58 2017 +0800  
   cherry-pic again  
 …

-S“<string>”内容,搜索新增或删除某行代码相关的commit,可以查出“new”这个单词是在哪个commit中加入的。如果要用正则表达式匹配,使用-G

$ git log -S"new" --oneline       
 fb41a26 add merge -- new dev   
 e00a40c branch test  

这个debug工具非常有用,可以定位到所有跟“<>”中代码相关的commit,甚至可以看出是什么时候被copy到另一文件中去的。

查看范围内的commit:

$ git log <since>..<until>

当使用branch作为range参数的时候,能很方便的显示2个branch之间的不同。

$ git log master..dev --oneline   
 9dbd3bc cherry-pic again   
 9942412 cherry-pick in branch dev   
 6388117 set upstream to  .---- dev branch   

输出的结果是master..dev这个range包含了在dev有而master没有的所有的commit,如图:(反之,dev..master包含所有master有但是dev没有的commit)

这里写图片描述

no-merges 过滤merge commit

merges 只输出merge commit

9.版本回退

———— >>> 即用分支的内容覆盖暂存区的内容 (在git中用HEAD表示当前分支当前版本)

9.1 查看历史操作记录

$ git reflog

9.2 回到某个版本

$ git reset –hard commitId

回退到上个版本,这里HEAD代表当前版本,上一个版本就是HEAD^,上上个版本就是HEAD^^(继续往上可以简化为:HEAD~n, n代表往上多少个版本)

$ git reset –hard HEAD^

HEAD实际是一个指向当前版本的指针,当你回退这个版本的时候,仅仅是把指针移动了,然后顺便把工作区的文件更新了
如果你还想返回到会退前的版本,找到对应的commit id 回退即可:git reset –hard commitId
这里写图片描述
这里写图片描述

总结:

a.想回退到未来,查看下命令历史 > $ git reflog
b.回退到过去用git log 来打印日志,找到相应commit

9.3 将文件XX暂存区的东西放回工作区

$git reset HEAD XX

git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当使用HEAD时,表示最新的版本。

10.git checkout

撤销文件XX工作区的修改 ———— >>> 即用暂存区的内容覆盖工作区的内容 (注意不能漏掉”–”)

$ git checkout –XXX

指定一个文件回到某个commit时的版本,工作目录的file文件会完整的copy指定commit中文件的内容。并且会被添加到stage区中

$ git checkout <commit-ID> <file>

工作目录所有文件都回退到某个commit时的状态,只读状态,在这里进行的任何修改都不会影响到项目,与上面的checkout文件不同(会影响项目)

$ git checkout <commit-ID>

基于某分支B创建另一分支A

$ git checkout -b XXA origin XXB

切换到分支XX

$ git checkout XX

加上-b表示创建并切换

$ git checkout -b XX

相当于以下两条命令: git branch XX + git checkout XX

Example:

   $ git checkout origin/master
  Note: checking out 'origin/master'.

  You are in 'detached HEAD' state. You can look around, make experimental
  changes and commit them, and you can discard any commits you make in this
  state without impacting any branches by performing another checkout.

  If you want to create a new branch to retain commits you create, you may
  do so (now or later) by using -b with the checkout command again. Example:

    git checkout -b &lt;new-branch-name>

  HEAD is now at 3e74a7a... merge bug fixed in issue1

11.删除工作目录中所有没有tracked过的文件

git clean经常和git reset –hard 结合使用,reset只影响被track过的文件,所以需要clean来删除没有track过的文件,两者结合使用能让工作目录完全回到某个commit。能轻易删除编译后产生的.o和.exe等文件,在打包的要发布一个release的时候非常有用。

$ git clean -n clean的演习,告诉你哪些文件会被删除,不会真正删除文件。

$ git clean -f 删除当前目录下所有没有被track的文件,不会删除.gitignore文件里面指定的文件夹和文件,不管这些文件track与否。

$ git clean -f <path> 删除指定路径下没有被tracked的文件。

$ git clean -df 删除当前目录下没有被track过的文件和文件夹。

$ git clean -xf 删除当前目录下所有没有被track过的文件,不管他是否是.gitignore文件里指定的文件和文件夹。

12.从版本库中删除某文件

执行后仍需commit将修改同步到版本库

$ git rm XX

13.操作分支

查看当前分支

$ git branch

查看本地所有分支

$ git branch -a

查看远程分支

$ git branch -r

新建分支

$ git branch <branch_name>

基于某分支创建新的分支

$ git branch <new-branch_name> <old_branch_name>

基于某次提交创建新的分支,此处需要找到对应的commit的code

$ git branch <new_branch_name> <commit code>

删除分支XX

$ git branch -d XX

要删除一个未被提交的分支XX,必须强制删除:

$ git branch -D XX

14.合并分支,此指令是将XX分支内容合并至当前分支

gitmergeXX git rebase XX

若有冲突,Git用<<<<<<<<,=============,>>>>>>>>>标记出冲突的内容,<<< HEAD后的内容表示当前分支内容

//参考pdf地址:Fast-forward Merge && Typical Merge https://sandofsky.com/images/fast_forward.pdf
Fast-forward 合并,直接移动HEAD指针,log里没有任何合并记录
这里写图片描述

禁用Fast-forward,Git就会在merge时生成一个新的commit
这里写图片描述

//–no-ff 表示禁用Fast-forward,因为本次合并要创建一个新的commit,so要加上-m,把commit描述写进去

$ git merge –no-ff -m “commit description” XX

Example:

  *   54727cc ----------merge with no-ff  ———-- >>>>> 2.2 master --on-ff merge from dev 
  |\ 
  | * 0a95587 new merge -- --no-off   ———-- >>>>> 2.1 dev commit 
  |/  
  * fb41a26 add merge -- new dev         ————— >>>>> 1. dev commit , and master merge dev  
  *   5c102fd conflict fixed -- in master 
  |\ 
  | * 773006b And Simple ---- featural 
  * | 24cbab1 & simple ---- master 
  |/ 
  * 02b2f2d branch txfest 
  * e00a40c branch test 
  * 8be51a1 append GPL 
  * df7c2de initial repository 

说明:
-1.是dev commit, and master merge from dev,仅仅是HEAD移动,在log这里我们看不到任何关于dev分支的信息,信息丢失。
-2.1是dev commit again,2.2是master –no-ff merge from dev,合并且再次生成一次commit
总结:可以看到 ff 和 no ff 的区别。

分支策略:
在实际开发中,master分支应该是非常稳定的,仅用来发布新版本。开发应该在dev分支上,也就是dev分支不稳定,到需要发布的时候再把dev合并到master上,在master发布新版本。团队每个人都有自己的分支,不时的将各自分支合并到dev上就可以。
这里写图片描述

15.将当前工作压入stash中

15.1 需要临时切换分支,但是不希望commit当前分支的code,又希望保存当前工作内容,就可以用以下命令来解决:

在当前需要保存的分支 -A 执行:

$ git stash

然后切到需要工作的分支 -B,当-B 的工作完成后,切回 -A.查看分支状态:

  $ git status
   On branch dev
   nothing to commit, working tree clean

可以看到工作区是干净的,那么刚才stash的内容去哪里了呢?
查看stash的记录:

  $ git stash list
   stash@{0}: WIP on dev: 0a95587 new merge -- --no-off
15.2 如何取出stash中的内容呢:有两种方法取出:

a.用命令:

$ git stash apply

取出,但是stash的内容不删除,需要用以下命令:

$ git stash drop

b.可以直接用

$ git stash pop

取出,这个指令相当于上面两个指令。再查看stash list 就看不到任何内容了。

也可以多次stash,取出的时候,先查看stash list,再用指令指定取出:

$git stash apply stash@{0}

16.git remote

查看远程分支,不带选项的时候,git remote命令列出所有远程主机

gitremote git remote show

查看主机的详细信息

$ git remote show <主机名>

使用-v选项,可以查看远程主机:origin 及其地址.. ,如果没有推送权限,看不到push地址

$ git remote -v

克隆版本库的时候,所使用的远程主机自动被Git命名为origin,要用其他的主机名,需要指定新的远程主机名otherOrigin

$ git clone -o otherOrigin https://github.com/

添加远程仓库(添加远程仓库地址)

$ git remote add <主机名> <https://… 即url>

删除远程主机(删除原有的远程仓库地址)

$ git remote rm <主机名>

修改远程主机名

$ git remote rename <原主机名><新主机名>

Example:

  $ git remote            
   origin
  $ git remote show
   origin
  $ git remote -v         
   originhttps://github.com/valyn/TestRepository.git (fetch) 
   originhttps://github.com/valyn/TestRepository.git (push) 
  $ git remote show origin
   * remote origin
     Fetch URL: https://github.com/valyn/TestRepository.git 
     Push  URL: https://github.com/valyn/TestRepository.git 
     HEAD branch: master
     Remote branches:
       dev    tracked
       master tracked
       newb   tracked
     Local branches configured for 'git pull':
       master merges with remote master
       newb   merges with remote newb
     Local refs configured for 'git push':
       master pushes to master (local out of date)
       newb   pushes to newb   (up to date)

修改git远程仓库地址,可以通过删除添加来做

gitremotermorigin git remote add origin [url]

17.多人协作的工作模式

指定push/pull分支

gitpushoriginXX git pull origin XX

在某些场合(例如git clone),Git会自动在本地分支与远程分支之间建立tracking。也可以手动建立tracking.

$ git branch –set-upstream-to=origin dev

Example:

   $ git checkout -b dev origin/dev   
    //新建一个分支dev,不能同时设置,提示在本地创建后通过commit同步到远程
    //解决方法:  1.通过提示方法解决  2.先执行  > $ git fetch ,再次执行本语句
    fatal: Cannot update paths and switch to branch 'dev' at the same time.
    Did you intend to checkout 'origin/dev' which can not be resolved as commit?
   $ git branch
    * master 
   $ git branch dev
   $ git checkout dev
    Switched to branch 'dev'
   $ git pull        //pull失败,当前工作目录分支和远程的仓库分支之间没有链接关系,根据提示设置他们之间的关系
    There is no tracking information for the current branch.
    Please specify which branch you want to merge with.
    See git-pull(1) for details.

        git pull &lt;remote> &lt;branch>

    If you wish to set tracking information for this branch you can do so with:

        git branch --set-upstream-to=origin/&lt;branch> dev

   $ git branch --set-upstream-to=origin dev   //把远程分支和本地分支关联起来,这样以后每次需要push或pull的时候,只需要输入git push或者git pull即可。 
    Branch dev set up to track remote branch master from origin.
   $ git pull
    Already up-to-date.
   $ git push
    fatal: The upstream branch of your current branch does not match
    the name of your current branch.  To push to the upstream branch
    on the remote, use

        git push origin HEAD:master

    To push to the branch of the same name on the remote, use

        git push origin dev

    To choose either option permanently, see push.default in 'git help config’.
   $ git push origin dev    //在只需要输入git push 或者git pull之前,必须要指定想要push或者pull的远程分支 git push origin master \ git pull origin master
    Counting objects: 3, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 343 bytes | 0 bytes/s, done.
    Total 3 (delta 1), reused 0 (delta 0)
    remote: Resolving deltas: 100% (1/1), completed with 1 local objects.
    To https://github.com/valyn/TestRepository.git 
     * [new branch]      dev -> dev

18.git fetch

从远程获取最新版本commit-id,记录到.git/FETCH_HEAD文件,不会自动merge到本地分支

$ git fetch

取回所有分支branch的更新

$ git fetch <远程主机名>

如果只想取回特定分支,可以指定分支名

$ git fetch <远程主机名> <分支名>

19.git pull

从远程获取远程主机某个分支的更新,再merge至本地指定分支,相当于git fetch和git merge。使用上,git fetch更安全一些,可以在merge前,检查下更新情况
完整格式如下;
如果是当前分支与远程分支合并,冒号后面部分可省略;
如果当前分支与远程分支存在tracking,远程分支名也可以省略;
如果当前分支只有一个tracking branch,远程主机名也可以省略。

$ git pull <远程主机名><远程分支名>:<本地分支名>

20.推到远程仓库

完整指令与git pull相仿

$ git push <远程主机名><本地分支名>:<远程分支名>

如果省略远程分支名,则表示将本地分支推送到与之有tracking关系的远程分支,如果该分支不存在,则新建并推送。
如果省略本地分支名,则表示删除指定的远程分支,因为这等于推送空的本地分支到远程分支。

Example:

  $ git push origin :master
     ===>equal 
  $ git push origin --delete master

如果当前分支与远程分支之间存在tracking,则本地分支和远程分支都可以省略 :

$ git push origin

如果当前分支只要一个tracking分支,主机名也可以省略。
如果当前分支与多个分支存在追踪关系,可以加上-u参数,指定默认主机,关联分支,之后就可以不加参数使用git push

$ git push -u origin master //将本地的master分支推送到origin主机,同时指定origin为默认主机

Simple方式:不带任何参数的git push,默认只推送当前分支
matching方式:推送所有有对应的远程分支的本地分支,Git 2.0版本之前,默认采用matching方法,现在改为默认采用simple方式。如果要修改这个设置,可以采用git config命令。

gitconfigglobalpush.defaultmatching git config –global push.default simple

不管是否存在对应的远程分支,将本地所有分支都推送到远程主机

$ git push –all <主机名>

如果远程分支比本地版本要新,不允许推送,如果要强制推送使用—force.(除非非常确定,应尽量避免使用–force)

$ git push –force <主机名>

git push不会推送tag,除非加上–tags。

$ git push <主机名> –tags

Example:

  $ git fetch origin master
  $ git pull origin   //表示当前本地分支与对应的主机 remote-tracking branch 进行合并 

21.cherry-pick

在实际使用中,可能会碰到在A分支上提交了一个更新,但是突然发现同样需要在B上应用这个更新,这个时候cherry-pick就能够帮助解决问题

$ git cherry-pick commit-id

Example:

  //首先,要通过git reflog在A分支上找到相应的commit-id,然后切换到B,执行以下
  $ git cherry-pick 9dbd3bc
   error: Your local changes would be overwritten by cherry-pick.
   hint: Commit your changes or stash them to proceed.
   fatal: cherry-pick failed
  $ git commit -m 'cherry first'
   [newb e57742a] cherry first
    Date: Mon Jan 9 15:04:26 2017 +0800
    1 file changed, 3 insertions(+)
  $ git push
   Counting objects: 3, done.
   Delta compression using up to 4 threads.
   Compressing objects: 100% (3/3), done.
   Writing objects: 100% (3/3), 348 bytes | 0 bytes/s, done.
   Total 3 (delta 1), reused 0 (delta 0)
   remote: Resolving deltas: 100% (1/1), completed with 1 local objects.
   git pTo https://github.com/valyn/TestRepository.git 
      3e74a7a..e57742a  newb -> newb
  $ git pull
   Already up-to-date.
  $ git cherry-pick 9dbd3bc
   error: could not apply 9dbd3bc... cherry-pic again
   hint: after resolving the conflicts, mark the corrected paths
   hint: with 'git add &lt;paths>' or 'git rm &lt;paths>'
   hint: and commit the result with 'git commit'
  $ git status
   On branch newb
   Your branch is up-to-date with 'origin/newb'.
   You are currently cherry-picking commit 9dbd3bc.
     (fix conflicts and run "git cherry-pick --continue")
     (use "git cherry-pick --abort" to cancel the cherry-pick operation)

   Unmerged paths:
     (use "git add &lt;file>..." to mark resolution)

   both modified:   readme.txt 

   no changes added to commit (use "git add" and/or "git commit -a")
  $ open readme.txt
  $ git add readme.txt
  $ git commit -m "fix cherry-pick conflict"
   [newb f432ad7] fix cherry-pick conflict
    Date: Mon Jan 9 15:12:58 2017 +0800
    1 file changed, 2 insertions(+)
  $ git push
   Counting objects: 3, done.
   Delta compression using up to 4 threads.
   Compressing objects: 100% (3/3), done.
   Writing objects: 100% (3/3), 336 bytes | 0 bytes/s, done.
   Total 3 (delta 1), reused 0 (delta 0)
   remote: Resolving deltas: 100% (1/1), completed with 1 local objects.
   To https://github.com/valyn/TestRepository.git 
     e57742a..f432ad7  newb -> newb

22.创建标签

默认标签,直接打在最新的commit上

$ git tag <tag-name>

找到对应的commit,打标签也可

$ git tag <commit-id> <tag-name>

查看标签 ————>>> 注意标签是按字母排序的

$ git tag

查看标签以及该commit信息

$ git show <tag-name>

还可以创建带有说明的标签

$ git tag -a <tag-name> -m “tag description” <commit-id>

通过-s用私钥签名一个标签

$ git tag -s <tag-name> -m “tag description” <commit-id>

签名采用PGP签名,因此,必须先安装gpg(GnuPG),如果没有找到gpg,或者没有gpg密钥对,就会报错:

 $ git tag -s v0.2 -m "signed version 0.2 released" 54727cc
   error: cannot run gpg: No such file or directory
   error: could not run gpg.
   error: unable to sign the tag

GPG签名是不可伪造的,因为可以验证GPG签名。验证签名较复杂,有兴趣的可以自行了解。

删除标签,标签都存在本地,打错的标签可以在本地安全删除

$ git tag -d <tag-name>

推送标签到远程

$ git push origin <tag-name>

一次性推送所有的远程本地标签

$ git push origin –tags

删除远程标签,先从本地删除

$ git tag -d <tag-name>

再删除远程

gitpushorigin:refs/tags/<tagname> git push origin –delete tag <tag-name>
$ git push origin : <tag-name>

23.prune :删减,修剪

若远程分支删除了某分支,默认情况下,git pull不会再拉取远程分支的时候删除对应的本地分支。这是为了防止,由于其他人操作了远程主机,导致git pull不知不觉删除了本地分支。
-p参数,就会在本地删除远程已经删除的分支。

$ git pull -p

等同于

gitfetchpruneorigin git fetch -p

24.amend

合并缓存区的修改和最近一次的commit,生成新的commit替换到最近那次的commit,如果缓存区没有内容,那么利用amend修改上一次commit的描述。

$ git commit –amend

–no-edit能让我们修复commit,但是不修改commit描述(commit 仍被新的替换)

$ git commit –amend –no-edit

不要对公共的commit使用amend。
amend或生成的commit是全新的,修改其他开发者使用的commit,会影响其他开发者。

Example:

  $ open readme.txt
  $ git add readme.txt
  $ git commit -m 'alter'
   [master c96ff44] alter
    1 file changed, 1 insertion(+)
  $ git log --oneline -2
   c96ff44 alter 
   3e74a7a merge bug fixed in issue1 
  $ open readme.txt
  $ git add readme.txt
  $ git commit —amend
   /* 此时会进入vim 模式修改commit描述 */
   [master 455e34c] alter --- amend
    Date: Fri Jan 13 15:24:24 2017 +0800
    1 file changed, 1 insertion(+)
   //修改完,再次log可以看到最后的commit的commit hash值不一样
  $ git log -2 --oneline
   455e34c alter --- amend 
   3e74a7a merge bug fixed in issue1 

25.回滚修改

git revert和git reset
这种回滚是有痕迹的,再生成一次提交,将之前的某次提交反向修改回来,不影响之前的提交。

$ git revert <commit code>

Example:

  Revert:
  $ git log --oneline --decorate --graph
   * 42721e3 - (HEAD -> master) alter --- amend 
   *   3e74a7a - (tag: v1.0, origin/master) merge bug fixed in issue1 
   |\ 
   | * 1e628db - fix issue in issue1 
   |/ 
   * 47e0f91 - fix bug - 101 
   . . . . . . (略)
  $ git revert 1e628db
   [master 627cc41] Revert "fix issue in issue1" 
    1 file changed, 1 insertion(+), 1 deletion(-)
  $ git log --oneline --decorate --graph
   * 627cc41 - (HEAD -> master) Revert "fix issue in issue1" 
   * 42721e3 - alter --- amend 
   *   3e74a7a - (tag: v1.0, origin/master) merge bug fixed in issue1 
   |\ 
   | * 1e628db - fix issue in issue1 
   |/ 
   * 47e0f91 - fix bug - 101 
   . . . . . . (略)
   //可以看到红色加粗部分就是新生成的提交,而revert的commit- 1e628db 到最新的commit仍然还在。
   Reset:
  $ git log --oneline --decorate --graph
   * 627cc41 - (HEAD -> master) Revert "fix issue in issue1" 
   * 42721e3 - alter --- amend 
   *   3e74a7a - (tag: v1.0, origin/master) merge bug fixed in issue1 
   . . . . . . (略)
  $ git reset 42721e3 
   Unstaged changes after reset:
   Mreadme.txt
  $ git log --oneline --decorate --graph
   * 42721e3 - (HEAD -> master) alter --- amend 
   *   3e74a7a - (tag: v1.0, origin/master) merge bug fixed in issue1 
   . . . . . . (略)
  //reset之后,reset那个commit后面的commit被删除了,但是里面的内容—-->> 被放回了暂存区,等待处理(可以重新commit,或者clean/checkout)

26.rebase模式

较复杂,再了解

二、Git使用

http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137628548491051ccfaef0ccb470894c858999603fedf000
1.参与修改开源项目
假设你当前在bootstrap项目主页,点击Fork就在自己的账号下克隆了一份bootstrap仓库,然后clone到本地就能进行修改。
一定要在自己的账号下clone,这样才能推送修改,如果直接从项目仓库clone到本地,因为没有权限,就不能推送修改。
2.Git可以fork任意开源仓库,自己拥有Fork后的仓库读写权限,可以发起一个pull request想官方申请接受你的修改。

三、Git配置

1.让命令输出显示颜色

$ git config –global color.ui true

2.设置别名

//告诉Git,st是status的别名,简写,偷懒相当好用

$ git config –global alias.st status

相似的

gitconfigglobalalias.cmcommit git config –global alias.co checkout
$ git config –global alias.br branch

..等等..

3.为命令段设置别名

例如:

3.1

$ git config –global alias.unstage ‘reset HEAD’

那么当执行下来语句的时候:
gitunstagetest.txt git reset HEAD test.txt

3.2

$ git config –global alias.last ‘log -1’

这样,用git last就能显示最近一次的提交

3.3

$ 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
   *   3e74a7a - (HEAD -> master, tag: v1.0, origin/newb, origin/master) merge bug fixed in issue1 (6 days ago) <git> 
   |\ 
   | * 1e628db - fix issue in issue1 (6 days ago) <git> 
   |/ 
   * 47e0f91 - fix bug - 101 (6 days ago) <git> 
   *   54727cc - ----------merge with no-ff (6 days ago) <git> 
   |\ 
   | * 0a95587 - new merge -- --no-off (6 days ago) <git> 
   |/ 
   * fb41a26 - add merge -- new dev (6 days ago) <git> 
   *   5c102fd - conflict fixed -- in master (6 days ago) <git> 
   |\ 
   | * 773006b - (tag: v0.1) And Simple ---- featural (6 days ago) <git> 
   * | 24cbab1 - & simple ---- master (6 days ago) <git> 
   |/ 
   * 02b2f2d - branch test (6 days ago) <git> 
   * e00a40c - branch test (6 days ago) <git> 
   * 8be51a1 - append GPL (6 days ago) <git> 
   * df7c2de - initial repository (7 days ago) <git> 

介个就变成了酱紫!!!
这里写图片描述
关于上面的参数,经过我的各种尝试,得出一下结论,仅供参考:
%C代表新的格式开始,后一定要跟着属性
reset跟在%C就表示从reset为默认属性,默认字体为黑色
%C后面➕颜色可设置字体颜色,可把颜色放在()中
%d相当于–decorate (HEAD -> master, tag: v1.0, origin/newb, origin/master)
%s表示commit的内容 branch test
%cd表示的是commit date Fri Jan 6 17:52:54 2017 +0800
%cr就变成了 6 days ago
%an表示提交人 git
%cn表示提交人 git

–global参数是全局参数,也就是这些命令在当前用户的所有Git仓库都适用。
–system是整台PC,即所有用户都适用。
每个repository的Git配置文件都放在.git/config文件中;
而当前用户的Git配置文件放在用户主目录(cd ~或者是cd /Users/XX)下的一个隐藏文件.gitconfig中。
以上全局参数均放在用户主目录下。
查看.git/config文件,查看当前Git配置:

  $ cat .git/config
   [core]
         repositoryformatversion = 0
         filemode = true
         bare = false
         logallrefupdates = true
         ignorecase = true
         precomposeunicode = true
   [remote "origin"]
         url = https://github.com/valyn/TestRepository.git 
         fetch = +refs/heads/*:refs/remotes/origin/*
   [branch "master"]
         remote = origin
         merge = refs/heads/master
   [branch "dev"]
         remote = origin
         merge = refs/heads/dev
   [alias]
         l2 = log -2

查看.gitconfig:

“`
cd  cat .gitconfig
[core]
excludesfile = /Users/ValynCheng/.gitignore
[difftool “sourcetree”]
cmd = opendiff \”> LOCAL\"\"> REMOTE\”
path =
[mergetool “sourcetree”]
cmd = /Applications/SourceTree.app/Contents/Resources/opendiff-w.sh \”> LOCAL\"\"> REMOTE\” -ancestor \”> BASE\"merge\"> MERGED\”
trustExitCode = true
[user]
name = git
email = valyncheng@foxmail.com
[filter “hawser”]
clean = git hawser clean %f
smudge = git hawser smudge %f
required = true
[color]
ui = true
[alias]
st = status
cm = commit
ck = checkout
br = branch
last = log -1
lg = log –color –graph –pretty=format:’%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset’ –abbrev-commit

“`

二者别名都跟在[alias]后面,要删除别名,直接把对应行删掉即可。
配置别名也可以直接修改文件,如果改错了,可以删除文件重新通过命令配置。

参考:
http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137583770360579bc4b458f044ce7afed3df579123eca000

https://www.sitepoint.com/git-for-beginners/

https://news.cnblogs.com/n/210635/

等等。。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值