zoukankan      html  css  js  c++  java
  • Git的简单使用

    1,创建仓库

       建立仓库目录

    mkdir rep

    2,初始化仓库

      使用如下命令

    git init

      初始化后会产生隐藏文件.git

      初始化成功之后配置一下自己的个人信息:

    $ git config --global user.name "Your Name"
    $ git config --global user.email "email@example.com"

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

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

    使用如下命令查看配置信息:

    git config -l

    3,仓库添加文件

    git add readme.txt

    Unix的哲学是“没有消息就是好消息”,说明添加成功。

    4,提交文件到仓库

    git commit -m "first file"

    命令格式和svn类似,SVN提交文件命令为:svn commit -m "first file"

    5,修改文件提交文件,查看当前仓库状态

    git status

    结果如下

    On branch master
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git checkout -- <file>..." to discard changes in working directory)
    
        modified:   readme.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")

    看到文件状态为被更改

    6,差分查看修改的内容

    使用如下命令

    git diff readme.txt

    结果如下

    diff --git a/readme.txt b/readme.txt
    index 5bd6a90..3b62fc4 100644
    --- a/readme.txt
    +++ b/readme.txt
    @@ -1,2 +1,3 @@
     Git is a version control system.
     First time to modified!
    +Second time to modified!

    7,提交修改

    和SVN不同的是提交前要先add然后再commit

    8,查看提交记录

    git log
    commit d9334820e9f8746578868808d113fc6b8f3360f1
    Author: xxxxxx <xxxxxx@163.com>
    Date:   Tue Feb 7 23:49:56 2017 +0800
    
        Secmond time to modified
    
    commit 97321e6d811c2c2dc2f2fce8e270676480af8b72
    Author:  xxxxxx <xxxxxx@163.com>
    Date:   Tue Feb 7 23:29:58 2017 +0800
    
        first time to modifed
    
    commit 0fc77bb42c42482b355fed5960a5338c2db2ca25
    Author:  xxxxxx <xxxxxx@163.com>
    Date:   Tue Feb 7 23:19:42 2017 +0800
    
        first file

    提交日志按时间降序排列

    如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数:

    $ git log --pretty=oneline
    d9334820e9f8746578868808d113fc6b8f3360f1 Secmond time to modified
    97321e6d811c2c2dc2f2fce8e270676480af8b72 first time to modifed
    0fc77bb42c42482b355fed5960a5338c2db2ca25 first file

    需要注意的是前面一长串d9334820e9f8746578868808d113fc6b8f3360f1是版本号,这有别于SVN,SVN是连续的正整数。这是因为git是分布式的版本管理系统,每个仓库的版本号都不能重复。

    9,回退版本

    在git中用HEAD表示当前版本,也就是最新提交的d9334820e9f8746578868808d113fc6b8f3360f1版本,上一个版本就是HEAD^,上两个版本是HEAD^^,往前100个版本HEAD~100.

    $ git reset --hard HEAD^

    输出结果如下

    $ git reset --hard HEAD^
    HEAD is now at 97321e6 first time to modifed

    查看日志如下

    $  git log
    commit 97321e6d811c2c2dc2f2fce8e270676480af8b72
    Author: zealzhangz <tenderfacepalm@163.com>
    Date:   Tue Feb 7 23:29:58 2017 +0800
    
        first time to modifed
    
    commit 0fc77bb42c42482b355fed5960a5338c2db2ca25
    Author: zealzhangz <tenderfacepalm@163.com>
    Date:   Tue Feb 7 23:19:42 2017 +0800
    
        first file

    如果还想回到之前最新的版本,需要知道版本号

    git reset --hard d93348
    git reset --hard d93348
    HEAD is now at d933482 Secmond time to modified

    然后又回到最新版本了,版本号d93348不一定要写全,但是要能唯一确定一个版本。

    如果版本号已经不记得了,可以使用git reflog,git reflog用来记录你的每一次命令

    $git reflog

    结果如下

    $ git reflog
    d933482 HEAD@{0}: reset: moving to d93348
    97321e6 HEAD@{1}: reset: moving to HEAD^
    d933482 HEAD@{2}: commit: Secmond time to modified
    97321e6 HEAD@{3}: commit: first time to modifed
    0fc77bb HEAD@{4}: commit (initial): first file

    这样就能查找到相关的版本号了。

    盗张图:

    详细可参考:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013744142037508cf42e51debf49668810645e02887691000

    10、工作区和暂存区

    工作区:GIT存储文件的物理目录,比如我当前的/Documents/dev/p/rep目录。工作区有一个隐藏的.git目录,和svn类似,svn也有一个隐藏目录.svn。可以把.git称之为版本库目录(Respository Directory)里面存储了git的很多配置信息。最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

    盗图如下:

    回顾前面的提交文件到git分两步走:

    第一步、git add ,实际上是把文件添加到暂存区。

    第二部、git commit ,实际上是把内容提交到当前分支。我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。

    因此我们可以分多次把文件提交到暂存区,然后一次性commit。

    需要注意的是:commit只会提交本次暂存区里面的文件,没有add到暂存区的文件,在commit时是不会提交到分支的。

    使用如下命令可以对比工作区和最新版本库的区别:

    git diff HEAD -- readme.txt

    11、撤销修改

      1)只在工作区进行了修改没有add

    $ git status
    On branch master
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git checkout -- <file>..." to discard changes in working directory)
    
        modified:   readme.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")

    Git会告诉你,git checkout -- file可以丢弃工作区的修改

    因此使用如下命令丢弃工作区的修改

    $ git checkout -- readme.txt 
    $ git status
    On branch master
    nothing to commit, working tree clean

    注意:如果有多次修改,并且已经有几次add到暂存区,那么git checkout -- readme.txt 命令将会回到添加到暂存区后的状态,也就是执行命令后工作区修改的内容被丢弃了,并且和当前暂存区一致。git checkout -- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令

      2)修改已经add到暂存区

    $ git status
    On branch master
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    
        modified:   readme.txt

    Git同样告诉我们,用命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区:

    git reset HEAD readme.txt 
    Unstaged changes after reset:
    M    readme.txt
    $ git status
    On branch master
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git checkout -- <file>..." to discard changes in working directory)
    
        modified:   readme.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")

      3)修改已经add且commit

      可以按照上面回退版本的方法进行回退,不过,这是有条件的,就是你还没有把自己的本地版本库推送到远程,因为Git是分布式版本控制系统。

    12、删除文件

      使用如下两个命令

    $git rm del.txt
    $git commit -m "deleted file"  del.txt
    $git rm del.txt 
    rm 'del.txt'
    $ ls
    LICENSE    readme.txt
    $ git status
    On branch master
    Changes to be committed:
      (use "git reset HEAD <file>..." to unstage)
    
        deleted:    del.txt

    13、远程仓库

    git本地仓库与GitHub远程仓库协同工作

    1)注册GitHub账号不走略过,在本地使用如下命令生成公钥并上传到GitHub

    $ssh-keygen -t rsa -C "myemail@163.com"

    一路回车后就生成好了公私钥文件在用户的根目录,注意目录是隐藏的。

    $ ls
    config      id_rsa      id_rsa.pub  known_hosts

    拷贝公钥内容id_rsa.pub到GitHub

    2)添加GitHub远程库并同步本地git库到GitHub

    建好库之后我们根据提示选择推送本地已经有的库到刚建好的GitHub远程仓库。

    把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。

    $ git remote add origin https://github.com/xxxxx/learngit.git
    $ git push -u origin master
    Username for 'https://github.com': xxxxxx
    Password for 'https://xxxxxx@github.com': 
    Counting objects: 30, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (23/23), done.
    Writing objects: 100% (30/30), 2.49 KiB | 0 bytes/s, done.
    Total 30 (delta 8), reused 0 (delta 0)
    remote: Resolving deltas: 100% (8/8), done.
    To https://github.com/xxxxxxx/learngit.git
     * [new branch]      master -> master
    Branch master set up to track remote branch master from origin.

    由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。推送成功后,可以立刻在GitHub页面中看到远程库的内容已经和本地一模一样.

    3)从远程仓库克隆

    上一节讲的是如果先有了本地项目,如何同步到GitHub远程仓库。如果我们是一个新的项目,从零开始的项目,最好先在远程仓库上创建然后再克隆到本地工作。创建仓库参照上一步骤,创建好之后我们使用以下命令进行克隆。

    $ git clone git@github.com:zealzhangz/clonerepository.git
    Cloning into 'clonerepository'...
    The authenticity of host 'github.com (192.30.253.113)' can't be established.
    RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'github.com,192.30.253.113' (RSA) to the list of known hosts.
    remote: Counting objects: 3, done.
    remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
    Receiving objects: 100% (3/3), done.

    GitHub给出的地址不止一个,还可以用https://github.com/michaelliao/gitskills.git这样的地址。实际上,Git支持多种协议,默认的git://使用ssh,但也可以使用https等其他协议。使用https除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能用https

    14、创建与合并分支

    分支的概念就不多讲了,原理和SVN分支的概念如出一辙。下面讲一下创建并且管理分支的一些命令:

      1)创建并切换分支

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

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

    $ git branch dev
    $ git checkout dev

      2)查看当前分支

    $ git branch
    * dev
      master

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

      3)切换分支

    $ git checkout master
    Switched to branch 'master'
    Your branch is up-to-date with 'origin/master'.

    4)合并分支

      把dev分支合并到master分支,首先切换到master分支,然后使用以下命令合并:

    $ git merge dev
    Updating 6a61034..17447bc
    Fast-forward
     readme.txt | 1 +
     1 file changed, 1 insertion(+)

    注意到上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。合并完成后,就可以放心地删除dev分支了:

    $ git branch -d dev
    Deleted branch dev (was 17447bc).

    查看当前分支信息:

    $ git branch
    * master

      5)常用命令小结

        查看分支:git branch

        创建分支:git branch <name>

        切换分支:git checkout <name>

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

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

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

    15、解决冲突

    使用上面的学习的命令git checkout -b feature1创建并切换分支到feature1分支,然后分支上更改文件并提交,切换到master分支,切换到master分支时会有如下提示:

    $ git checkout master
    Switched to branch 'master'
    Your branch is ahead of 'origin/master' by 1 commit.

    会提示feature1分支比master分支超前一个commit。

    更改同一行,并提交,现在分支情况如下:

    这种情况下git无法执行快速合并,只能试图把各自的修改合并起来,但是这种合并就会有冲突,比如两个分支更改了同一行。产生冲突如下:

    $ git merge feature1
    Auto-merging readme.txt
    CONFLICT (content): Merge conflict in readme.txt
    Automatic merge failed; fix conflicts and then commit the result.

    查看状态如下:

    $ git status
    On branch master
    Your branch is ahead of 'origin/master' by 3 commits.
      (use "git push" to publish your local commits)
    You have unmerged paths.
      (fix conflicts and run "git commit")
      (use "git merge --abort" to abort the merge)
    
    Unmerged paths:
      (use "git add <file>..." to mark resolution)
    
        both modified:   readme.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")

    此时打开文件手动修复冲突:

      1 Git is a version control system.
      2 First time to modified!
      3 Second time to modified!
      4 Git is a free software
      5 Git has a mutable index called stage.
      6 Git tracks changes.
      7 acbcd
      8 switch brance
      9 <<<<<<< HEAD
     10 Creating a new branch iS quick AND simple.
     11 =======
     12 Creating a new branch IS quick AND simple.
     13 >>>>>>> feature1
    以下表示当前版本的内容

    9 <<<<<<< HEAD
     10 Creating a new branch iS quick AND simple.
     11 =======
    以下表示feature1分支当前版本的内容
     11 =======
     12 Creating a new branch IS quick AND simple.
     13 >>>>>>> feature1

    因此需要手动解决冲突如下
      1 Git is a version control system.
      2 First time to modified!
      3 Second time to modified!
      4 Git is a free software
      5 Git has a mutable index called stage.
      6 Git tracks changes.
      7 acbcd
      8 switch brance
      9 Creating a new branch is quick AND simple.

    再次提交

    $ git add readme.txt 
    $ git commit -m "resolved conflict"
    [master d1c25a1] resolved conflict

    现在两个分支情况如下

    使用git log -graph查看分支合并情况

    git log --graph --pretty=oneline --abbrev-commit
    *   d1c25a1 resolved conflict
    |  
    | * 371a890 feature1 second commit
    * | 8998da9 master second commit
    |/  
    * 03fef75 feature1
    * 17447bc commit brance
    * 6a61034 delete file
    * d7d12ed 123
    * 781f988 deleted file
    * a30f515 delete test.txt
    * 23702d1 add test.txt
    * bb2a69a git tracks changes
    * 53638b2 understand how stage works
    * 4bbda7e changed
    * d933482 Secmond time to modified
    * 97321e6 first time to modifed
    * 0fc77bb first file

    最后删除feature1分支

    $ git branch -d feature1
    Deleted branch feature1 (was 371a890).

     16、分支管理策略

    通常情况下合并分支时git会使用fast forward模式,这种模式下删除分支后会丢掉分支信息。如果禁用Fast forward模式git会在merge分支时生成一个新的commit,这样就可以保存分支的历史信息。

    下面实战一下加上参数--no-ff方式的git merge。

    1)首先建立并切换分支更改readme.txt文件并提交

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

    2)切换到master分支并加上--no-ff并merge到master分支

    $ git merge --no-ff -m "merge with no-ff" dev
    Merge made by the 'recursive' strategy.
     readme.txt | 1 +
     1 file changed, 1 insertion(+)
    $ git log --graph --pretty=oneline --abbrev-commit
    *   4d3f53d merge with no-ff
    |  
    | * 950fa74 --no-ff git merge
    |/  
    *   d1c25a1 resolved conflict
    |  
    | * 371a890 feature1 second commit
    * | 8998da9 master second commit
    |/  
    * 03fef75 feature1
    * 17447bc commit brance
    * 6a61034 delete file
    * d7d12ed 123
    * 781f988 deleted file
    * a30f515 delete test.txt
    * 23702d1 add test.txt
    * bb2a69a git tracks changes
    * 53638b2 understand how stage works
    * 4bbda7e changed
    * d933482 Secmond time to modified
    * 97321e6 first time to modifed
    * 0fc77bb first file

    不使用Fast forwar模式merge就如下图:

    开发中管理分支的几个基本策略:

    ①master分支为稳定发布分支,也可以叫release分支,每次往生产环境发布的分支

    ②Dev分支为开发分支,每位开发者分别从Dev分支拉自己的开发分支,本地测试通过后提交到Dev分支,等待测试小组测试通过了merge到master分支发布。

    ③feature/bug分支,如果增加了新功能且改动较大做好重新拉一个分支,待开发结束后再合并到Dev分支、再合并到master分支,bug分支或者经紧急对应分支,每次生产报了一个阻塞用户或者比较紧急的bug可以单独拉一个分支对应。如果bug不紧急可以等到下次正常发布一起。

    盗图如下:

    17、保存现场stash功能

    有这样一个场景,我正在开发新功能,开发到一半突然来个紧急bug要修。新功能一时半会开发不完,因此已经更改或新建的新功文件能不能和bug一起提交。这个时候就需要保留开发到一半的现场,等我修完bug再接着开发,因此git有stash(存储,储存的意思)功能来保留现场。实战如下:

    $ git status
    On branch master
    Your branch is up-to-date with 'origin/master'.
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git checkout -- <file>..." to discard changes in working directory)
    
        modified:   readme.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")
    $ git stash
    Saved working directory and index state WIP on master: 4d3f53d merge with no-ff
    HEAD is now at 4d3f53d merge with no-ff
    $ git status
    On branch master
    Your branch is up-to-date with 'origin/master'.
    nothing to commit, working tree clean

    可以看到执行git stash命令后查看工作区状态就是干净的.

    现在要执行如下步骤修bug,完成后并回复工作区间

    ①切换到指定分支一般是当前的稳定分支(trunk)分支并拉出bug分支

    ②在bug分支issure-001修复bug后提交

    ③切换到trunk分支合并bug分支并发布

    ④好了之后可以删除bug分支切换到刚开始的Dev分支恢复之前的工作现场继续开发

    注意:这里的工作区间可以恢复到任何分支,比如刚创建的分支,但可能会有冲突需要解决

    恢复stash有两种方法:

    法一:

    使用git stash list查看当前的保存的工作区间列表,使用git stash apply stash@{0}来进行恢复,这种恢复方式,恢复之后之前保存的stash还是存在的,不会被删除。需要手动删除。

    $ git stash list
    $ git stash apply stash@{0}
    $ git stash drop

    法二:

    git stash pop,恢复的同时把stash内容也删了

    $ git stash pop

    详细操作步骤如下:

    $ git checkout master

    $ git checkout -b issure-001
    Switched to a new branch 'issure-001'
    $ vim readme.txt 
    $ git add readme.txt 
    $ git commit -m "fix bug 001"
    [issure-001 821f542] fix bug 001
     1 file changed, 1 insertion(+), 1 deletion(-)
    $ git checkout master
    Switched to branch 'master'
    Your branch is up-to-date with 'origin/master'.
    $ git merge --no-ff -m "merged bug fix 001" issure-001
    Merge made by the 'recursive' strategy.
     readme.txt | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    $ git stage list
    fatal: pathspec 'list' did not match any files
    $ git stash list
    stash@{0}: WIP on master: 4d3f53d merge with no-ff
    $ git branch -d issure-001
    Deleted branch issure-001 (was 821f542).
    $ git checkout -b dev
    Switched to a new branch 'dev'
    $ git stash list
    stash@{0}: WIP on master: 4d3f53d merge with no-ff
    $ git branch
    * dev
      master
    $ git stash apply stash@{0}
    Auto-merging readme.txt
    CONFLICT (content): Merge conflict in readme.txt
    $ git stash list
    stash@{0}: WIP on master: 4d3f53d merge with no-ff
    $ git stash drop
    Dropped refs/stash@{0} (417d5d4606fde5e2e92f9c7659e38d498caa6b63)
    $ git status
    On branch dev
    Unmerged paths:
      (use "git reset HEAD <file>..." to unstage)
      (use "git add <file>..." to mark resolution)
    
        both modified:   readme.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")
  • 相关阅读:
    zhcon安装过程记录
    diff和patch配合使用(转载备用)
    Linux /etc/passwd 和 /etc/group 文件格式
    APT 常用功能
    Linux邮件服务器架构
    出现segment fault 错误的几种原因
    位运算
    Linux启动过程中几个重要配置文件的执行过程
    2016-2017 ACM-ICPC, South Pacific Regional Contest (SPPC 16)
    Codeforces Round #439 (Div. 2) 题解
  • 原文地址:https://www.cnblogs.com/maxiaofang/p/6376411.html
Copyright © 2011-2022 走看看