zoukankan      html  css  js  c++  java
  • git整理

    git特点:
    1- 直接记录快照,而非差异比较。以快照流的方式对待数据。对所有文件制作一个快照,保存这个快照的索引。如果文件没有改动,git只是简单保留一个链接指向之前存储的文件。
    2- 近乎所有操作都是本地执行,所以很快。例如svn如果断网了就无法提交。

    git三种状态:
    已提交(committed): 修改进入了本地数据库中
    已修改(modified): 修改了,但未保存到数据库中
    已暂存(staged): 将修改的文件快照放入暂存区等待提交

    git三个区域概念(Working tree, staging area, and Git directory):
    git仓库目录(.git):git用来存储项目元数据和对象数据库的地方
    工作目录: git仓库的压缩数据库中提取出来的某个版本
    暂存区: 是一个保存了待提交文件的信息,放在git仓库目录中

    HEAD的概念:
    HEAD就是指向当前分支的最后一个提交的指针
    HEAD可以简写成@。    HEAD~N表示顺着自己这一脉(主线,git log --graph的左边)上溯N个提交。  HEAD^表示上溯一个提交(等效于HEAD^1,这里的1表示主线,2表示被合并的提交<假设存在,git log --graph的右分支>), HEAD^^^表示主线上溯3个提交(等效于HEAD^^^1)。

    获取帮助:
    git help <verb>     #例如git help config
    git <verb> --help
    man git-<verb>

    获取一个仓库(repository):
    途径1: 克隆远程仓库。 执行git clone <remote_repo> [directory]会从服务器仓库上拉取源码文件的所有版本
    途径2: 初始化一个本地仓库。在有源码的目录中执行git init命令初始化一个仓库,在目录下会生成.git仓库目录。此时没有任何文件被跟踪


    基本流程:
    1-修改文件
    2- git add <pathspec>...                     # 跟踪<pathspec>指定的目录或文件,也就是将它们纳入版本控制。同时这些文件也进入了暂存区,等待提交。
    3- git commit -m "初始化工程"           #提交到本地git仓库(也就修改的快照进入.git仓库目录)

    注意 git add 命令是个多功能命令。1-可以用它开始跟踪新文件; 2-把已跟踪的文件放到暂存区; 3-还能用于合并时把有冲突的文件标记为已解决状态...等功能。
               git commit是将暂存区的快照提交到git仓库
               所以,执行git add后,修改的快照进入了暂存区待commit,如果此时又修改了文件,那么修改还在工作区中,需要再次git add才能将新的修改放入暂存区。

    配置:
    git配置文件可以使用git config命令来读写:
           1.   /etc/gitconfig 作用于系统级 git config 加 --system选项时读写此文件
           2.  ~/.gitconfig 或 ~/.config/git/config 作用于当前用户 git config 加 --global选项时读写此文件
           3.  当前仓库目录下的.git/config 作用于当前仓库目录对应的仓库 工作目录是该仓库,且git config 不加参数时,读写此文件
    每一个级别覆盖上一级别的配置,所以 .git/config 的配置变量会覆盖 /etc/gitconfig 中的配置变量。

    重要命令
    git config --list                         #列出当前配置
    git config <key>                      # 查看某项配置,例如 git config core.editor
    git config <key> <value>        # 修改某项配置,例如: git config --global core.editor vim

    远程仓库操作:

    git clone -b master https://a.cn/x/y.git      # 只克隆master分支(对于很大的仓库或网速很慢时挺有用的)
    git remote -v                                            # 查看远程分支, 加-v参数不但显示远程仓库短名字,还显示它的长名字。 origin是git clone给远程仓库默认生成的短名字,长名字就是那串长长的url:https://a.com/foo/bar
    git remote show origin                             # 查看远程仓库origin的所有远程分支,这条命令可以查看本地分支跟踪的是哪个远程分支。(设置跟踪参考下面git push -u的说明)
    git branch -r                                            # 列出远程仓库的所有分支以及远程仓库的默认分支是哪个(例如origin/HEAD->origin/master)。 “git ls-remote [远程仓库短名字]” 也是类似功能的命令
    git remote add <远程短名字> <url>         # 关联远程仓库(远程仓库存在的情况下才执行这条命令)。一个本地仓库可以关联多个远程仓库
    git fetch origin  dev:Dev                          #  从远程仓库origin下载数据,指定远程仓库的dev下载到对应本地仓库Dev。语法: git fetch   <远程短名>  [远程分支][:本地分支]   直接执行git fetch会从默认追踪的远程分支下载
    git pull                                                     # 是git fetch 和git merge的组合,参数指定方式参考上面的git fetch,我通常不适用git pull , 而是git fetch,然后再git merge。
    git push origin  LB:rb                              # 推送本地分支LB到远程仓库origin的rb分支。如果远程仓库origin没有rb分支,则会在远程origin下新建一个rb分支。如果直接执行git push那么就将本地分支推送到默认的远程仓库。如果本地仓库关联多个远程仓库,可以直接执行git push fooRep来指定将本地分支的变更推送到远程仓库fooRep下。如果推送的时候,提示没有对应的上游分支可以增加-u选项(--set-upstream选项的缩写)来建立对远程分支的跟踪,一旦使用-u来跟踪远程分支了,后面直接git push,不用跟其他参数了。这里我们执行git remote show origin就会看到本地的LB追踪了远程仓库origin的rb分支
    git push --all origin                                 # 不管本地是否存在对应的origin远程分支,都会将本地的所有分支都推送到远程主机.
    git rename origin gitee_foo                    # 把远程仓库名origin重命名为gitee_foo
    git remote rm gitee_foo                         # 删除远程仓库,也可以: git push origin --delete dev //假设远程仓库短名是origin
    注意: 一般而言,dev、debug之类的分支是不需要推送到远程仓库的,一般是把这些分支合并到master分支后,推送master到远程仓库

     

    分支操作:
    git branch                                                      #查看分支 -v 或 -vv会显示详细信息
    git branch --merged                                      #查看所有已合并的分支, 同理 --nomerged查看所有未合并的分支
    git branch <branchName>                            #创建分支
    git branch <brName> <commitID>                #以某个commitID来创建分支,非常有用
    git checkout <branchName>                         #切换分支, 加-b参数标示创建并切换分支
    git checkout origin/br0                                  #对于远程clone下来的仓库origin,切换到它的br0分支
    git checkout -b <local-br> <remote>/<br>     #创建一个与远程分支remote/br相对应的本地分支  #针对特定标签建分支
    git checkout -b <brName> <tag>                  #针对特定标签建分支
    git merge <branchName>                             #合并分支到当前分支。 通常合并分支时,git一般使用”Fast forward”模式,禁用FF模式,需要加参数--no-ff ( 非FF合并后的历史有分支,能看出来曾经做过合并,而FF看不出来)
    git branch –d <branchName>                       #删除分支-D表示强制
    git branch -u <remote>/<brName>               # 设置已有的本地分支来跟踪一个刚刚拉取下来的远程分支。 -u的长选项格式是--set-upstream-to。 此时@{u}或@{upstream}是<remote>/<brName>的快捷方式。所以git merge @{u}相当于git merge <remote>/<brName>
    git push origin --delete branch1                  #删除远程分支, 也可以写成 git push origin :branch1 

     注意master分支应该是非常稳定的,一般不在上面干活。在dev分支上干活,然后将稳定了的dev分支合并到master分支。团队协作是各个成员将自己分支不断合并到dev分支。

    工作进度隐藏:
    git stash save "stash_comment"       #保存完成一半的工作, 此时git status提示是干净的。
    git stash list                                       #列出已经隐藏的git栈
    git stash apply stash@{N}                 #恢复到stash N
    git stash clear                                   #清除缓存的stash
    git stash pop                                     #将stash从git栈中弹出
    git drop stash@{N}                           #删除某个stash
    git stash show stash@{N}                #查看某个stash

    比较差异:
    git diff   [<path>...]                                         #使用默认对比工具来比较
    git difftool   [<path>...]                                   #使用第三方工具比较差异, 例如BeyondCompare。关于将beyondCompare用于git,参考另一篇文章 
    git diff/difftool [file]                                         #对比工作区和暂存区的差别(git add之前的)
    git diff/difftool --staged [file]                           #对比暂存区和上次commit的差别
    git diff/difftool  <commit-id> <commit-id>       #比较两个版本(用commit-id指定)的差异
    git diff/difftool HEAD  [file]                              #比较工作区和最后一次commit的差异
    git diff/difftool  master  ReadMe.txt                #比较当前分支和master分支的ReadMe.txt文件的差异 
    git log dev ^master                                        # 比较dev分支有,而master分支没有的提交
    git log master..dev                                        # dev比master多了哪些提交? ..可以理解为from->to
    git log master...dev                                       # 不知道谁的提交多,只是想比较有哪些提交差异.加--left-right 参数可以显示提交所属的分支是哪个(例如git log --left-right master...dev 的<箭头表示master的)
    git whatchanged <file>                                 # 查看某个文件的变更的详细提交记录,简单记录可以使用git log --pretty=oneline  <file>。 查看完后,可以git show <commit-id> [file]或者git difftool <commit-id1> <commit-id2> [file]来查看具体变更
    git blame <file>                                             # 显示文件的每一行最后变更的commit id

    撤销修改 / 版本回退 :
    git  checkout  --  ReadMe.txt proto.c          #从暂存区中恢复文件到工作区。也就是执行add之前反悔了。这里的"--"表示选项的结束,如果没有任何选项,可以省略 "--"
    git  reset  --soft  <commit-id>                     # HEAD移动到 commit-id 指定的那个提交(不是针对单个文件或目录,所以参数中不能跟路径),也可以用HEAD~N的方式来指定重置到前N个版本。
    git  reset --hard  <commit-id>                    #HEAD暂存区工作区都重置到commit-id指定的提交(不是针对单个文件或目录,所以参数不带路径)。这个有点危险,如果误操作,只能通过git reflog 查一下历史操作的commit-id才能恢复
    git reset  --mixed  <commit-id>   [path]      #HEAD暂存区都重置到commit-id指定的提交,工作区不变, --mixed是默认选项,参数可以带路径(可以针对单个文件或目录执行重置)
    我测试的结果:   --soft是只重置HEAD指针, 工作区和暂存区不变。 不能带路径。
                               --hard是HEAD、暂存区和工作区都重置(危险操作) 。不能带路径。
                               --mixed是重置HEAD和暂存区(默认参数)。 工作区不变。可以带路径,但是带路径会有warning

    git revert  <commit-id>         #revert和reset的区别是,revert是将旧版本变成一个新的提交.  可以revert常规commit也可以revert分支合并的commit, 后者需要-m <1|2> 来指定保留哪个分支,1表示当前分支
    例如下面revert合并的commit:
    --A------B-----C------M----X----Y(revert)
       -----a-----b-------/
    如果当前处于上面分支X状态(此时上面分支有AaBbCX的提交), 如果Y处执行git revert -m 1 M的CommitID    则上面的分支只有ABCX的提交,(也就是丢弃了ab的提交)
                                                                                              如果Y处执行git revert -m 2 M的CommitID    则上面的分支只有AabX的提交(也就是丢弃了BC的提交). 注意这条命令是在Y处执行,而非上一条命令执行完后执行

    revert注意的地方,可以到https://segmentfault.com/a/1190000012897697看例子

    修改已完成的提交(commit后,可以多次修改该commit):
    例如:
    git add proto.c
    git commit -m '修正proto.c的bug' #突然发现漏了proto.h和gen_id.c,忘了移除tmp.txt,于是执行:
    git add proto.h gen_id.c
    git rm tmp.txt
    git commit --amend '修正proto.c和gen_id.c的bug' #此时git log --stat 只能看到修改后的提交

    删除文件:
    git rm <file> ; git commit -m 'xxxx'                   #删除工作区和暂存区文件,并且提交
    git rm --cached <file> ; git commit -m 'xxx'      #删除暂存区文件,并提交。此时工作区文件还在,这是版本库不再跟踪它了。

      

    查看提交历史:
    git log -3 #查看最近三次提交
    git log --after/before='1999-09-09'          #查看1999-09-09前/后的提交。 指定时间可以使用类似"1year"、“8days”之类的。 --after等同--since,--before等同于--until
    git log --author/--committer=<name>      #按作者/提交者查看,注意作者和提交者的区别
    git log --grep=<pattern>                          #按正则搜索注释
    git log hello.c                                          # 查看修改了hello.c的commit,查看针对某个路径的commit,如果有很多选项时,可以使用 -- 标示选项结束: liru
    git log --graph                                         #形象显示commit log
    git log --stat                                            #显示commit 历史涉及的文件
    git show --stat [commitID]                      #显示某个commit涉及的文件变更
    git log --pretty=format:%h" "%an" "%s    #显示短hash、作者、注释(空格分隔)。更多%号格式参考git lot help
    git log --pretty=oneline                           #单行显示commit历史
    git log  --  server.c                                  # 查看 server.c 的提交记录

    标签:
    git  tag                                                                                                   # 查看已有标签
    git  tag  -l  'v1.*'                                                                                     # -l是小写的L,只列出 v1.* 的版本号, 批配处v1.0 v1.1 v1.2...
    git  tag   v1.0                                                                                         # 打一个轻量级标签, 轻量级标签是对某个提交的引用。不指明commit-id的情况下,默认引用HEAD
    git  tag  -a   v2.0  -m '这是v2.0附注标签的说明'                                     # 打上一个附注标签,-a是的a是annoted的首字母。附注标签是一个仓库中的独立对象。它有自身的校验和信息,以及标签说明。
    git  tag  -s    v2.1 -m '这是v2.0附注标签的说明'                                     # 打上一个GPG签名的附注标签。 -s是signed的首字母. 使用git show v2.1会看到GPG签名
    git  show  v2.0                                                                                       # 查看标签v2.0的详情
    git  tag  -v  v2.1                                                                                     # 验证含有GPG签名的标签(keyring中需要有GPG公钥)
    git  tag  v1.2   df1796d00a50a5567fac0b7d689402942943e01d         # 给df1796d00a50a5567fac0b7d689402942943e01d这个提交打轻量标签
    git tag -a v2.3 -m '忘记打标签了'                                                           # 给df1796d00a50a5567fac0b7d689402942943e01d这个提交打附注标签
    git  push origin  v2.3                                                                             # 将标签推送到远程仓库origin。(默认情况下git push是不会推送标签的,所以需要专门推送标签,标签才能体现在远程仓库上)
    git  push  origin  --tags                                                                          # 将所有标签推送到远程仓库

    ------------------------------------ 注意力分割线 --------------------------------------

    我做的小测试:
    mkdir x; cd x
    git init
    git remote add ts2 https://gitee.com/xxx/test2
    git fetch ts2                                       # 抓取的副本在本地的工作空间是看不到文件的。ps: 可以git fetch ts2 dev 只fetch dev分支
    git checkout -b dev ts2/dev              #此时就可以看到ts2/dev对应的的本地dev分支了。此时执行 ls -l 就能看到工作空间有文件了
    上面的最后两步可以这么玩:
    git fetch ts2 dev:dev      #fetch ts2的dev分支,并在本地创建dev分支
    git checkout dev            #切换到本地dev分支,此时就能看到远程的ts2/dev分支在本地对应dev分支的工作空间文件了

    git checkout -b dev2      #建立本地dev2分支
    git push -u ts2 dev2      #把本地分支dev2 推送到远程分支ts2上,结果在gitee服务器上看到了dev2分支

  • 相关阅读:
    【React Native】某个页面禁用物理返回键
    【React Native】DeviceEventEmitter监听通知及带参数传值
    转载【React Native代码】手写验证码倒计时组件
    【React Native】 中设置 APP 名称、应用图标、为安卓添加启动图
    【React Native错误集】* What went wrong: Execution failed for task ':app:installDebug'.
    【React Native错误集】Import fails with "Failed to execute 'ImportScripts' on 'WorkerGlobalScope'"
    【React Native错误集】Android error “Could not get BatchedBridge, make sure your bundle is packaged properly” on start of app
    「React Native笔记」在React的 setState 中操作数组和对象的多种方法(合集)
    【React Native】Error: Attribute application@allowBackup value=(false) from AndroidManifest.xml
    坚果云如何使用二次验证码/谷歌身份验证器/两步验证/虚拟MFA?
  • 原文地址:https://www.cnblogs.com/mind-water/p/git.html
Copyright © 2011-2022 走看看