• git之一: git基础


    参考: SourceTree使用

              git教程

              廖学风git

        文档1

        文档2

    1. git 概念介绍

    • 工作区: 就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区,工作区下面有.git目录
    • 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。 Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区, 还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。

    git 文件的4中状态:

    git库所在的文件夹中的文件大致有4种状态
    
    Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过git add 状态变为Staged.
    
    Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified. 如果使用git rm移出版本库, 则成为Untracked文件
    
    Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git checkout 则丢弃修改过, 返回到unmodify状态, 这个git checkout即从库中取出文件, 覆盖当前修改
    
    Staged: 暂存状态. 执行git commit则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify状态. 执行git reset HEAD filename取消暂存, 文件状态为Modified
    

    2. git常用命令

    命令大概图解

    创建配置版本库

    1. git init  #用于本地版本库的创建
    
    "git init --bare #创建一个裸仓库(用于服务器版本库创建),裸仓库没有工作区,服务器上的Git仓库纯粹
    是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,
    把owner改为git。
    
    2. git config --global user.email "you@example.com" #配置提交作者
       git config --global user.name "Your Name"

    添加文件到版本库

    1. git add files  或者 git add .  #添加文件到暂存区(stage)

    git add -A 将工作区中的所有改动以及新增文件添加到暂存区。

    git add -i #选择性添加到stage
    2. git commit -m "描述"

    回退和查看

    1. git status  #查看加入到暂存区(stage)的文件和工作区文件的改动,可以回退,(git reset filename 回退,从暂存区撤销出来.)
    git status -s
    2. git log 或者 git log dev # 查看分支的提交

    git log  --oneline #查看更加简短的提交id,这个id也是可以使用的,比如在reset 或者revert命令中。

      git log  --oneline --decorate #查看带有 tag的
    简短的提交id

    git log --stat -2 #查看最新的2次提交
    3. git show 0a87317d6a8ccd3a5145c4d2668b63918a5de4e8 #查看某一个具体的提交 

    4.git show-branch --more=10 #查看当前分支简洁单行摘要

    5. 一个文件修改了很多行,如何让它回到最开始没有更改的状态
    git chechkout -- filename

    [root@chehce a1]# vim 2.txt
    [root@chehce a1]# git status
    # On branch master
    # Your branch is ahead of 'origin/master' by 3 commits.
    # (use "git push" to publish your local commits)
    #
    # Changes to be committed:
    # (use "git reset HEAD <file>..." to unstage)
    #
    # new file: test
    #
    # 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: 2.txt
    #

    [root@chehce git]# git rev-list HEAD                #查看提交的所有cimmitid
    e7bb519a7b89c85e52c5e2fea076d19e072abe34
    a80132df92811ec377f1659014ccb0430f0e038e
    9b526cb779001a371b252a180d9403da5d391ce8
    990c9e00b023405c9f34ff3b4783b9147d8a6d26
    a56abde92aeebe9bcd33bac309891de57ca07a2e
    9eb33d3c55803cd9e989859e91af547eefb9a4b3
    50df03d3229824e4f4a4a4a3972e23565eff1b27
    8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f
    [root@chehce git]# git log --oneline 
    e7bb519 add 6.txt
    a80132d add 5.txt
    9b526cb 修改ha.txt
    990c9e0 mv haha.txt to ha.txt
    a56abde Merge commit '9eb33d3c55803cd9e989859e91af547eefb9a4b3'
    9eb33d3 haha
    50df03d 2-4
    8b0d08c touch 1.txt

    删除,重命名

     
    将版本库中的文件删除或者重命名
    
    git rm filename  --------> git commit -m "删除filename" #2步完成
    
    如: 在客户端执行 git rm t1.sh , git commit -m "删除t1.sh" 后,
    
        再git push到服务器.另外一个客户端再git pull后,本地的t1.sh也被删除了。
    
    
    git mv data newdata: 如
    
        git mv f1 f1.bak
    
        git commit -m "mv f1 to f1.bak" #通过2步完成



    注意: 直接rm 删除或者 mv移动只是改变了个工作区,暂存区是没有改变的。要将暂存区删除得用上面的 git rm --cache 或者git reset

    忽略文件

    在work dir 或者它的子目录 新建 文件 .gitignore 文件,将要忽略的文件写入其中,那么在 git add 的时候就可以忽略掉这些文件。

    可以使用匹配。例如  *.h 表示 所有.h 结尾的文件。

    [root@chehce git]# ls
    1.txt  2.txt  3.txt  4.txt  5.txt  6.txt  ha.txt
    [root@chehce git]# touch {1..5}.h           #新建了几个文件
    [root@chehce git]# ls
    1.h  1.txt  2.h  2.txt  3.h  3.txt  4.h  4.txt  5.h  5.txt  6.txt  ha.txt
    [root@chehce git]# ls
    1.h  1.txt  2.h  2.txt  3.h  3.txt  4.h  4.txt  5.h  5.txt  6.txt  ha.txt
    [root@chehce git]# vim .gitignore   #编辑忽略文件
    [root@chehce git]# git status       #查看git 状态的时候,并没有提示那些文件需要 git add。 但是提示了 忽略文件自身.
    # On branch master
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #    .gitignore
    nothing added to commit but untracked files present (use "git add" to track)

    忽略掉自身

    [root@chehce git]# cat .gitignore 
    *.h
    .gitignore                        #文件中加入自己
    [root@chehce git]# git status
    # On branch master
    nothing to commit, working directory clean

    文件归档

    git branch

    git branch #查看本地分支

    git branch -a #查看本地和远程的所有分支

    git branch dev #创建分支

    git checkout dev #切换分支

    git branch -D dev 删除本地分支

    git push origin :br 删除远程分支

    #例子:在本地仓库创建分支,提交内容,然后push到远程仓库.另外一个客户端再pull远程仓库。

    本地仓库的操作:
    
    git branch dev
    
    git checkout dev
    
    touch test-dev.txt
    
    git add test-dev.txt
    
    git commint -m "add test-dev.txt"
    
    
    #将本地dev分支push到远程仓库的dev分支(远程仓库不存在dev分支会创建)
    git push origin dev:dev #origin 代表远程仓库,dev(本地分支):dev(远程分支)
    
    #再另外一个git客户端pull的时候,是在master客户端执行的。只能pull到master客户端。
    git pull #在客户端master分支上pull只能pull到远程仓库的master分支。
    
    #将远程仓库分支到本地与本地dev分支合并。
    git pull origin dev:dev

    git pull

    • 将远程存储库中的更改合并到当前分支中。在默认模式下,git pull是 git fetch后跟git merge FETCH_HEAD的缩写。

    • 更准确地说,git pull使用给定的参数运行git fetch,并调用git merge将检索到的分支头合并到当前分支中。 使用–rebase,它运行git rebase而不是git merge。

    • 示例

    $ git pull <远程主机名> <远程分支名>:<本地分支名>
    
    比如,要取回origin主机的next分支,与本地的master分支合并,需要写成下面这样 -
    
    $ git pull origin next:master
    
    如果远程分支(next)要与当前分支合并,则冒号后面的部分可以省略。上面命令可以简写为:
    
    $ git pull origin next

    git push

    • git push命令用于将本地分支的更新,推送到远程主机。它的格式与git pull命令相似。

    $ git push <远程主机名> <本地分支名>:<远程分支名>
    
    
    #将本地的master分支推送到origin主机的master分支。如果master不存在,则会被新建。
    
    $ git push origin master
    
    #如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。
    
    $ git push origin :master
    # 等同于
    $ git push origin --delete master
    
    
    #将当前分支推送到origin主机的对应分支。
    
    $ git push origin
    
    将本地的master分支推送到origin主机,同时指定origin为默认主机,
    后面就可以不加任何参数使用git push了。
    git push -u origin master
    • 不带任何参数的git push,默认只推送当前分支,这叫做 simple 方式。 此外,还有一种 matching 方式,会推送所有有对应的远程分支的本地分支。 Git 2.0 版本之前,默认采用 matching 方法,现在改为默认采用 simple 方式。 如果要修改这个设置,可以采用 git config 命令。

    • 还有一种情况,就是不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时需要使用–all选项。

    $ git push --all origin   将所有本地分支都推送到origin主机。

    如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做 git pull 合并差异,然后再推送到远程主机。 这时,如果你一定要推送,可以使用“`–force“ 选项。

    $ git push --force origin

    git merge

    • git merge命令用于将两个或两个以上的开发历史加入(合并)一起。

    将分支dev合并到当前分支中,自动进行新的提交:
    
    $ git merge dev

    git fetch

    • git fetch命令用于从另一个存储库下载对象和引用。远程跟踪分支已更新(Git术语叫做commit), 需要将这些更新取回本地,这时就要用到git fetch命令。取回的更新现在看不到必须merge后才能查看到内容

    要更新所有分支
    $ git fetch <远程主机名> = git fetch
    
    取回特定分支的更新,可以指定分支名
    $ git fetch <远程主机名> <分支名>
    
    取回远程主机的更新以后,可以在它的基础上,使用git checkout命令创建一个新的分支。
    $ git checkout -b newBrach origin/master
    
    
    
    也可以使用git merge命令或者git rebase命令,在本地分支上合并远程分支。在当前分支上,合并origin/master。
    $ git merge origin/master
    # 或者
    $ git rebase origin/master

    git 冲突

    首先,用git diff查看冲突在哪里,然后手动修改。

    也可用 git status查看, 可以告诉我们冲突的文件.

     
    $ git status  查看冲突的文件
    
    然后修改文件的冲突部分
    
    再次提交。
    $ git add readme.txt
    $ git commit -m "conflict fixed"

    3.  git  branch 

    创建分支

    git branch  branch-name   [starting commint]
    
    git branch t1 23fe826
    #如果没有starting comminit,,就默认从当前分支的最近提交创建分支.

    列出分支

    git branch #列出本地分支
    
    git branch -a #列出本地和远程分支

    git branch --merged #已经合并的分支.包括现在 所在的分支,master分支 和 新分支(未做任何开发提交)

    git branch --no-merged # 没有合并的分支。已经开发提交了的分支。但是还没合并过来的.

    切换分支

    git checkout branch-name

    合并分支

    git merge branch-name   #合并分支到本分支

    分支修改删除

    [root@chehce a1]# git branch  -m dev dev1   #修改
    [root@chehce a1]# git branch 
      dev1
    * master
      t1
    [root@chehce a1]# git branch  -d dev1  #删除
    Deleted branch dev1 (was fefba76).
    [root@chehce a1]# git branch  
    * master
      t1

    4. git的撤销和回滚

    1. git commint 之前 

     未添加到暂存区的撤销(没有git add),比如修改了文件(新增加文件没法撤销,只能手动删除文件).

    可以通过

     git checkout -- filename  来撤销修改
    # 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:   7.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")

    如果想将多个文件一次性撤销可以用,(用于撤销文件中内容的修改,新建文件不起作用)

     git checkout --   .

    要撤销新建的文件可以用:

    gti clean -fd

    添加到暂存区域的(执行了 git add 命令的),状态如下

    [root@chehce git]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #    modified:   6.txt
    #    modified:   7.txt
    #

    利用git reset file来撤销  , 随后 用  git checkout -- filename 。 这两步来回到没更改的状态.

    [root@chehce git]# 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:   6.txt
    #    modified:   7.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@chehce git]# git add  .
    [root@chehce git]# git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #    modified:   6.txt
    #    modified:   7.txt
    #
    [root@chehce git]# git reset .
    Unstaged changes after reset:
    M    6.txt
    M    7.txt
    [root@chehce git]# 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:   6.txt
    #    modified:   7.txt
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    [root@chehce git]# git checkout  -- .
    [root@chehce git]# git status
    # On branch master
    nothing to commit, working directory clean

    2. git commint 以后

    如果当commit提交后想撤销的话,这就需要revert命令。git revert 命令是撤销某次操作,而在此次操作之前和之后的提交记录都会保留。

    先修改了几个文件然后commit 再用git log查看提交记录。

    commit 2842c8065322085c31fb7b8207b6296047c4ea3
    Author: songguojun <songgj@kingnet.sh>
    Date:   Sat Apr 28 11:21:30 2018 +0800
    
        add content

    然后使用revert  后面跟上git提交的commitid

    git  revert 2842c8065322085c31fb7b8207b6296047c4ea3

    然后在推送到远端更新远程仓库代码,修改的文件就撤销回来了。注意的是revert奇数次生效,偶数次又回到之前的修改状态。比如一个文件内容是a,那么修改为ab,revert后文件变成了a,如果在revert后文件又还原成ab了。在上次revert的基础上再来一次 reavert就回到了原来。

    所以  git revert 是可逆的,该命令主要在对某些修改了的文件恢复到某个 状态,不管这个文件是在哪个时间修改的。然后又可以恢复回来.

    3.回到之前某个版本reset

    还有就是如果想回到之前某个版本,可以用reset命令,可以回退到某次提交,那次提交之后的提交都会回滚,不过这种覆盖是不可逆的,之前的提交记录都没有了。所以平时开发中尽量注意,避免使用reset。相当于这个版本的之后的添加的修改的文件全部都没有了。

    用法:

    git  reset --hard  commit_id
    • --hard – 强制将缓存区和工作目录都同步到你指定的提交

    git reset commit_id  查看日志的时候已经没有以前的提交记录,但是文件还没有被清理。  用  git clean -df 可以清理.就得到了回滚时候的状态. 

    这个时候,git服务器的版本肯定是领先本地reset后的版本,要想push的话,的用 -f 参数

     git push  -f origin  master:master 

    同理。其它的客户端想要pull也要用 -f

    git pull -f  origin master:master

    git reset 参数使用

     

    4.挽救reset 的重置

     git reflog show master  ,通过logs查看分支指向的变迁。 默认非裸版本库提供分支日志功能。

    [root@chehce git]# git reflog show master 
    8b0d08c master@{0}: reset: moving to 8b0d08c
    4889406 master@{1}: revert: Revert "Revert "touch 1.txt""
    f3002c2 master@{2}: revert: Revert "touch 1.txt"
    7612e4d master@{3}: commit: 4
    a4aaa0c master@{4}: commit: 3-4
    8b0d08c master@{5}: reset: moving to 8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f
    07d57c8 master@{6}: pull: Fast-forward
    8b0d08c master@{7}: reset: moving to 8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f
    78660cc master@{8}: revert: Revert "Revert "8""
    701a173 master@{9}: revert: Revert "8"
    5f02a91 master@{10}: commit: 8
    07d57c8 master@{11}: branch: Created from refs/remotes/origin/master

    注意:  最新的改变放在了最前面

    [root@chehce git]# git reflog  show master
    8b0d08c master@{0}: reset: moving to 8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f
    50df03d master@{1}: commit: 2-4
    8b0d08c master@{2}: reset: moving to 8b0d08c
    4889406 master@{3}: revert: Revert "Revert "touch 1.txt""
    f3002c2 master@{4}: revert: Revert "touch 1.txt"
    7612e4d master@{5}: commit: 4
    a4aaa0c master@{6}: commit: 3-4
    8b0d08c master@{7}: reset: moving to 8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f
    07d57c8 master@{8}: pull: Fast-forward
    8b0d08c master@{9}: reset: moving to 8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f
    78660cc master@{10}: revert: Revert "Revert "8""
    701a173 master@{11}: revert: Revert "8"
    5f02a91 master@{12}: commit: 8
    07d57c8 master@{13}: branch: Created from refs/remotes/origin/master
    [root@chehce git]# git reset --hard  master@{1}   #重置master为1次变更之前的值。
    HEAD is now at 50df03d 2-4
    [root@chehce git]# ls
    1.txt  2.txt  3.txt  4.txt

    修改 最新一次的提交说明

    更改最新一次的 提交 说明。

    git commit --amend -m "添加6.txt"          

    5. git cherry-pick (捡选,从其它分支捡选需要的 提交 到本HEAD(分支))

    参考: https://www.jianshu.com/p/4ac5f52d9210

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


    [root@chehce git]# git checkout dev
    Branch dev set up to track remote branch dev from origin.
    Switched to a new branch 'dev'
    [root@chehce git]# cat .git/HEAD   #当前版本是dev,也就是指向dev上最新的一个提交
    ref: refs/heads/dev
    [root@chehce git]# git checkout master 
    Switched to branch 'master'
    [root@chehce git]# cat .git/HEAD   #切换到master上, 当前版本是 master。
    ref: refs/heads/master

    举例:  有 A B C D E F 6个提交,现在要去掉提交D

    1.  上演第一幕: 干掉 D

    [root@chehce git]# git log  --oneline  --decorate -6   #查看6次提交
    3ba31ba (HEAD, tag: F, master) add F.txt
    144cb97 (tag: E) add E.txt
    7864377 (tag: D) add D.txt
    424dd1c (tag: C) add C.txt
    c22e544 (tag: B) add B.txt
    628e28c (tag: A) add A.txt
    [root@chehce git]# git checkout C   #切换到tag C
    Note: checking out 'C'.
    
    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 new_branch_name
    
    HEAD is now at 424dd1c... add C.txt
    [root@chehce git]# cat .git
    .git/       .gitignore  
    [root@chehce git]# cat .git/HEAD   #查看现在的HEAD 是指向 C
    424dd1c5c63353127836b86511868af18812125e
    [root@chehce git]# git cherry-pick  E   #将tag  E 选捡到当前
    [detached HEAD 5c8783e] add E.txt
     1 file changed, 1 insertion(+)
     create mode 100644 E.txt
    [root@chehce git]# git cherry-pick  F  #将 tag F 选捡到当前
     [detached HEAD 309f21e] add F.txt 1 file changed, 1 insertion(+) create mode 100644 F.txt 

    [root@chehce git]# git checkout master #切换到master
    Warning: you are leaving
    2 commits behind, not connected to
    any of your branches:
      309f21e add F.txt
      5c8783e add E.txt
    If you want to keep them by creating a
    new branch, this may be a good time
    to
    do so with:
      git branch new_branch_name 309f21e
    Switched to branch
    'master'

    [root@chehce git]# git reset
    --hard HEAD@{1} #将HEAD@{1}相当于切换回master分支前的指向。也就是 重新选捡后的tag F 的commintid, 也可以把HEAD@{1}直接换成
    重新选捡后的tag F 的commintid。可以看一下下面的演示。

    HEAD
    is now at 309f21e add F.txt

    [root@chehce git]# git log --oneline --decorate -5   #在次查看发现tag D 已经不在了。
    309f21e (HEAD, master) add F.txt
    5c8783e add E.txt
    424dd1c (tag: C) add C.txt
    c22e544 (tag: B) add B.txt
    628e28c (tag: A) add A.txt

    [root@chehce git]# git log  --oneline  --decorate
    3ba31ba (HEAD, tag: F, master) add F.txt
    144cb97 (tag: E) add E.txt
    7864377 (tag: D) add D.txt
    424dd1c (tag: C) add C.txt
    c22e544 (tag: B) add B.txt
    628e28c (tag: A) add A.txt
    cda8768 add 5.txt 6.txt
    9b526cb (tag: version1.0) 修改ha.txt
    990c9e0 mv haha.txt to ha.txt
    a56abde (tag: old_practice) Merge commit '9eb33d3c55803cd9e989859e91af547eefb9a4b3'
    9eb33d3 haha
    50df03d 2-4
    8b0d08c touch 1.txt
    [root@chehce git]# git log  --oneline  --decorate -6
    3ba31ba (HEAD, tag: F, master) add F.txt
    144cb97 (tag: E) add E.txt
    7864377 (tag: D) add D.txt
    424dd1c (tag: C) add C.txt
    c22e544 (tag: B) add B.txt
    628e28c (tag: A) add A.txt
    [root@chehce git]# git checkout C
    Note: checking out 'C'.
    
    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 new_branch_name
    
    HEAD is now at 424dd1c... add C.txt
    [root@chehce git]# cat .git
    .git/       .gitignore  
    [root@chehce git]# cat .git/HEAD 
    424dd1c5c63353127836b86511868af18812125e
    [root@chehce git]# cat .git/refs/
    heads/   remotes/ tags/    
    [root@chehce git]# cat .git/refs/heads/master 
    3ba31baf3649969d10d94b864b70828ce466fe81
    [root@chehce git]# 
    [root@chehce git]# git cherry-pick E
    [detached HEAD 433ac03] add E.txt
     1 file changed, 1 insertion(+)
     create mode 100644 E.txt
    [root@chehce git]# cat .git/refs/heads/master 
    3ba31baf3649969d10d94b864b70828ce466fe81
    [root@chehce git]# cat .git/HEAD 
    433ac03c1843c90a677eeef63ffc18b5eff875aa
    [root@chehce git]# git cherry-pick F
    [detached HEAD 48a27b6] add F.txt
     1 file changed, 1 insertion(+)
     create mode 100644 F.txt
    [root@chehce git]# cat .git/refs/heads/master 
    3ba31baf3649969d10d94b864b70828ce466fe81
    [root@chehce git]# cat .git/HEAD                         #现在  HEAD 的指针
    48a27b694a5c1820588716b6c51fb7b611b3e4d4
    [root@chehce git]# git checkout master
    Warning: you are leaving 2 commits behind, not connected to
    any of your branches:
    
      48a27b6 add F.txt
      433ac03 add E.txt
    
    If you want to keep them by creating a new branch, this may be a good time
    to do so with:
    
     git branch new_branch_name 48a27b6
    
    Switched to branch 'master'
    [root@chehce git]# cat .git/HEAD   #master的指针还是在master
    ref: refs/heads/master
    [root@chehce git]# git reset --hard 48a27b694a5c1820588716b6c51fb7b611b3e4d4     #将master的 指针指向上面 tag F 的HEAD
    HEAD is now at 48a27b6 add F.txt
    [root@chehce git]# git log --oneline --decorate
    48a27b6 (HEAD, master) add F.txt
    433ac03 add E.txt
    424dd1c (tag: C) add C.txt
    c22e544 (tag: B) add B.txt
    628e28c (tag: A) add A.txt
    cda8768 add 5.txt 6.txt
    9b526cb (tag: version1.0) 修改ha.txt
    990c9e0 mv haha.txt to ha.txt
    a56abde (tag: old_practice) Merge commit '9eb33d3c55803cd9e989859e91af547eefb9a4b3'
    9eb33d3 haha
    50df03d 2-4
    8b0d08c touch 1.txt
    HEAD@{1}的演示

    例子2: 

    从一个分支cherry-pick多个commit

     

    https://blog.csdn.net/amanicspater/article/details/78624973

    5. git检出

    HEAD(头指针) 的重置即检出。

    HEAD 指向了master分支.

    [root@chehce git]# cat .git/HEAD 
    ref: refs/heads/master
    [root@chehce git]# git checkout 8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f  #检出到commintID
    Note: checking
    out '8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f'. 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 new_branch_name HEAD is now at 8b0d08c... touch 1.txt [root@chehce git]# cat .git/HEAD #HEAD 头指针指向不在是master,指向了一个具体的提交ID 8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f

    # 新建文件并且提交

    [root@chehce git]# vim haha.txt 
    [root@chehce git]# git add  .
    [root@chehce git]# git commit -m "haha"
    [detached HEAD 9eb33d3] haha
     1 file changed, 1 insertion(+)
     create mode 100644 haha.txt
    [root@chehce git]# ls
    1.txt  haha.txt
    [root@chehce git]# cat .git/HEAD 
    9eb33d3c55803cd9e989859e91af547eefb9a4b3
    [root@chehce git]# git log 
    commit 9eb33d3c55803cd9e989859e91af547eefb9a4b3
    Author: che <che@example.com>
    Date:   Thu Jun 21 17:47:22 2018 +0800
    
        haha
    
    commit 8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f
    Author: chepingan <1139024190@qq.com>
    Date:   Thu Jun 21 11:55:13 2018 +0800
    
        touch 1.txt
    [root@chehce git]# git log --graph --pretty=oneline  #新的提交是建立在之前的提交上。
    * 9eb33d3c55803cd9e989859e91af547eefb9a4b3 haha
    * 8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f touch 1.txt

    切换回到 master分支,上面新建的文件不见了。日志里面也没有它的提交记录。如何让他可以到master分支呢? 合并,对将合并到master分支。

    git merge 9eb33d3c55803cd9e989859e91af547eefb9a4b3

    发现文件出现了。

    [root@chehce git]# git log --graph --pretty=oneline 
    *   a56abde92aeebe9bcd33bac309891de57ca07a2e Merge commit '9eb33d3c55803cd9e989859e91af547eefb9a4b3' #合并
    |  
    | * 9eb33d3c55803cd9e989859e91af547eefb9a4b3 haha  # 创建文件提交
    * | 50df03d3229824e4f4a4a4a3972e23565eff1b27 2-4  #检出到 commitid
    |/  
    * 8b0d08cf0f65d81fc5510c895f7a34d5adc7fd6f touch 1.txt

    6. git tag操作

     https://blog.csdn.net/wangjia55/article/details/8793577/

    标签也叫做里程碑。

     1. 标签列出和查看

    git tag   #查看当前分支下所有标签

    [root@chehce git]# git tag
    A
    old_practice

    git tag -l "*old*"   #过滤标签

    [root@chehce git]# git tag -l "*old*"
    old_practice

    git describe   #显示可从提交中获得的最新标签。

    [root@chehce git]# git describe 
    old_practice-2-g9b526cb     #这个表示的是在tag-修改次数-g现在的提交id.

    git log  --oneline  --decorate   #在提交id旁显示该提交的关联的引用(里程碑或者分支)。

    [root@chehce git]# git log  --oneline  --decorate 
    9b526cb (HEAD, master) 修改ha.txt
    990c9e0 mv haha.txt to ha.txt
    a56abde (tag: old_practice, origin/master) Merge commit '9eb33d3c55803cd9e989859e91af547eefb9a4b3'
    9eb33d3 haha
    50df03d 2-4
    8b0d08c (tag: A) touch 1.txt

    git show  标签名字

    [root@chehce git]# git show version1.0
    tag version1.0
    Tagger: che <che@example.com>
    Date:   Fri Jun 22 11:10:16 2018 +0800
    
    version 1.0
    
    commit 9b526cb779001a371b252a180d9403da5d391ce8
    Author: che <che@example.com>
    Date:   Fri Jun 22 10:43:40 2018 +0800
    
        修改ha.txt
    
    diff --git a/ha.txt b/ha.txt
    index 3740b8b..89f2424 100644
    --- a/ha.txt
    +++ b/ha.txt
    @@ -1 +1,3 @@
     afaf
    +afsf
    +11

    2. 打标签

    给当前这点打标签,不用跟其它的

    git tag  "标签名字" -m "说明"
    [root@chehce git]# git tag  "version1.0" -m "version 1.0"
    [root@chehce git]# git describe 
    version1.0
    [root@chehce git]# git log --oneline --decorate
    9b526cb (HEAD, tag: version1.0, master) 修改ha.txt
    990c9e0 mv haha.txt to ha.txt
    a56abde (tag: old_practice, origin/master) Merge commit '9eb33d3c55803cd9e989859e91af547eefb9a4b3'
    9eb33d3 haha
    50df03d 2-4
    8b0d08c (tag: A) touch 1.txt

    给某一个 commmint id 打标签

    git tag  "标签名字" commintID  -m "说明"
    [root@chehce git]# git tag "version1.2" e7bb519a7b89c85e52c5e2fea076d19e072abe34 -m "version 1.2"
    [root@chehce git]# git tag
    A
    old_practice
    version1.0
    version1.1
    version1.2
    [root@chehce git]# git log --oneline  --decorate
    e7bb519 (HEAD, tag: version1.2, master) add 6.txt
    a80132d (tag: version1.1) add 5.txt
    9b526cb (tag: version1.0) 修改ha.txt
    990c9e0 mv haha.txt to ha.txt
    a56abde (tag: old_practice, origin/master) Merge commit '9eb33d3c55803cd9e989859e91af547eefb9a4b3'
    9eb33d3 haha
    50df03d 2-4
    8b0d08c (tag: A) touch 1.txt

    3. 切换到标签(就相当于直接切换到某个commint ID)

    [root@chehce git]# git tag
    A
    old_practice
    version1.0
    version1.1
    [root@chehce git]# ls
    1.txt  2.txt  3.txt  4.txt  5.txt  ha.txt
    [root@chehce git]# git checkout version1.0   #切换到version1.0所引用的commint id。
    Note: checking out 'version1.0'.
    
    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 new_branch_name
    
    HEAD is now at 9b526cb... 修改ha.txt
    [root@chehce git]# git branch
    * (detached from version1.0)
      dev1
      master
    [root@chehce git]# ls
    1.txt  2.txt  3.txt  4.txt  ha.txt

    4. 删除标签

     git  tag -d "标签名字"

    [root@chehce git]# git tag  -d "version1.2"
    Deleted tag 'version1.2' (was da064c9)
    [root@chehce git]# git tag
    A
    old_practice
    version1.0
    version1.1

    5. 标签发布(提交,默认是不会提交到git服务器的)

    git push origin v0.1.2 # 将v0.1.2标签提交到git服务器
     git push origin –tags # 将本地所有标签一次性提交到git服务器

    [root@chehce git]# git push  --tags
    Counting objects: 3, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 418 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To 172.10.30.228:/root/test/git
     * [new tag]         A -> A
     * [new tag]         old_practice -> old_practice
     * [new tag]         version1.0 -> version1.0
     * [new tag]         version1.1 -> version1.1

    7. git服务器搭建

    git服务端

    • git服务器端和客户端可以位于同一台机器上。服务器端时用来协同多个开发客户端进行版本的同步,提供共享功能。

    • 第一步,安装git:

    $ sudo apt-get install git

    第二步,创建一个git用户,用来运行git服务:

    $ sudo adduser git

    第三步,创建证书登录:(也可直接用密码忽略这一步)

    收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,
    把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。

    第四步,初始化Git仓库:

    服务器上的Git仓库通常都以.git结尾。然后,把owner改为git
    
    $ sudo git init --bare sample.git  #--bare创建一个裸仓库,git服务器端使用。

    git权限配置

    sudo chown -R git:git sample.git
    
    usermod -s /usr/bin/git-shell git #出于安全考虑,第二步创建的git用户不允许登录shell.
    git用户可以正常通过ssh使用git,但无法登录shell,因为git用户指定的git-shell每次一登录就自动退出。

    git 客户端

     第一步:从服务器端克隆git版本库。

    git clone git@172.10.30.228:/opt/gamesoul.git

    第二步: 更改配置文件用于表明客户端的身份,要不然会跟服务端一样

    git config --global user.email "you@example.com"  #根据实际情况填写
    git config --global user.name "Your Name"
    
    git config -l

    第三步:git 客户端push一些文件到服务器。

    echo 111>1.txt
    git add 1.txt
    git commit -m "1.txt"
    git push  #客户端1 push到服务器
    
    git pull #客户端2 pull更新的文件到本地
    • 开发时,我认为一般是在master以外的分支上作开发,然后合并到本地master分支,再push到远程仓库

    • git 报错

     Git push 报错1:warning: push.default is unset; 解决如下
    
        //设置默认行为为simple。 Git2.0以后
         git config --global push.default simple
         //设置默认行为为matching。Git2.0以前
         git config --global push.default matching
    
    
    git push报错2:
    
         ! [rejected]        master -> master (fetch first)
        error: failed to push some refs to 'git@172.10.30.228:/opt/gamesoul.git'
    
        原因: 因为本地的内容和服务器上不同(服务器上有本地没有),解决
    
        先 git pull  ,在git push
  • 相关阅读:
    枚举类型
    [ Java学习 ] “goto语句“ 和 “continue + 标号” 的不同待遇
    [ Java学习 ] 其他知识总结(重要)
    [ Java学习 ] Java变量以及内存分配(非常重要)
    [ Java学习 ] 包语句 package等语句的汇总整理
    [ Java学习 ] 破除思维定势之 C++ 和 Java 的差异 003
    P1601一道高精度的题
    啊哈,我又来了
    算了,有一道水题
    再水一道题
  • 原文地址:https://www.cnblogs.com/yitianyouyitian/p/9057376.html
Copyright © 2020-2023  润新知