zoukankan      html  css  js  c++  java
  • Git Authoritative Guide 学习

    一、git命令
    1.git add
      -u : 将工作区中所有改动的文件添加到暂存区(修改、删除),但是不提交未被git跟踪的文件
      -i : 可以进入交互界面选择性提交
      -A : 相对于-u,它还提交新建的文件

    2.git format-patch -1 从获取最新一次提交的patch

       git format-patch -1 commit-id 获取某一次提交的patch,eg:$ git format-patch -1 0d7c516

    3.git grep :在工作区目录下查找,更高效

    4.git commit --amend 如果git commit时提交信息写错了可以使用它来修改,修改的是最新一次提交的
      eg:git commit --amend -m "use gitg to commit but qgit to change=="
      使用图形化窗口gitg或qgit修改更方便!gitg功能更强大!
      git rebase -i <hash> :如果修改的不是上一次提交,还要变基(目前还不知怎么用)

    5.git rm --cached new.txt 如果不小心把多余的文件添加到暂存区,如此时还没有commit,使用此删除记录(文件还在)
      git reset -- filename : 会把暂存区中的文件置为非staged的状态,为git add的反操作,同上。

    6.git rev-parse --git-dir 查看自己的git仓库在哪
      git rev-parse --show-toplevel 显示工作区根目录
      git rev-parse --show-prefix 显示当前目录与工作区的相对路径

          $ cat .git/config  可以得出 URL 远程版本库网址

          $ git ls-files :查看此版本库管理哪些文件

    7.git commit --allow-empty -m "this is empty commit" 没有任何修改也可提交--空白提交

    8.git log -s :simple
    git log --oneline :只显示一行commit信息

    9.git commit -sm "xxxx" : -s表示这次提交的信息中会自动包含提交的签名和邮箱地址

    10.git clean
      -fd : 会清除工作区中未在暂存区中的文件和文件夹
      -nd : 查看会删除那些文件,夹。

    11.git cat-file
      -t 哈希值 :显示此哈希值代表什么对象,commit(提交),bolb(文件),tree(目录)
      -p 哈希值 :打印此哈希值表示的对象的内容

    12.HEAD表示当前分支最新提交,^表示上一次提交

    13.git reflog show master 筛选显示master分支上的信息
      git reflog后使用 git status <hash>查看更改

    14.使用git reset --hard <hash> 后此hansh的提交会填充暂存区和工作区,之前的修改会丢失
      但是git reflog记录了所有提交信息,使用git reset --hard <old_hash>还会回到之前的状态

    15.git merge 对git check out迁出的无名分支merge到分支之上

    16.git checkout -- file : 会以暂存区的文件覆盖工作区的文件
      git checkout -- . 和 git checkout . 会丢弃掉工作区相对于暂存区的所有更改。
      只会对工作区中没有受到git管理的文件操作。

      git checkout <hash> <文件名>  此迁出此hash值时的此文件,例如$ git checkout 084e8df Makefile  常用的Makefile可以专门提交到一个分支中,使用时这样checkout出来,很方便。

    17.git ls-files --with-tree=HEAD^ 查看历史版本库中的文件列表

    18.git tag查看里程碑,也即是查看发布软件的版本号,
      git describe 描述距这个发布版本目前多了几次修改,最近的提交的hash值

    19..gitignore忽略文件:作用域为此目录及其根目录,只对git管理的文件进行忽略,在其中添加要被忽略的文件

    20.git archive -o last.zip HEAD   或者 last.tar.gz 归档打包操作,如果直接使用tar -cf xxxx会将此目录下的所有文件打包过去,无论是不是要忽略的文件

    21.查看一个命令的路径:which xxx

    22.git blame third.c 追溯一个文件的提交

    23.git diff : 工作区与暂存区
      git diff --cached 暂存区与版本库
      git diff HEAD 工作区与版本库
      git diff A :比较工作区和里程碑A
      git diff --cached A 比较暂存区和里程碑A
      git diff B A :比较里程碑B和里程碑A

    24.git log --stat -2 : 比直接-2多出了更改信息

    25.git checkout HEAD -- third.c 从版本库中取出third.c到暂存区和工作区

    26.将两次提交合并为一次提交:
      git reset --soft HEAD^^
      git commit -m "xxxxxxx"

    27.git show-ref 显示各应用哈希值

    28.git clone git@gitlab.com:xxxx/bmp.git manage :clone下拉后重命名为manage

    29. git status 用于对比工作区、暂存区、版本库之间的区别

    30.
      # git fsck 查看版本库中(包含暂存区和工作区)的未被任何应用关联的松散对象
      dangling blob 02a2010152982a96e1962cb98eb6d459cd8089af
      dangling:就是没有被任何应用直接或间接关联的对象
      若已经commit就会被记录在reflog中,使用git fsck --no-reflogs查看,然后将.git/logs下面
      清空(此时git log正常显示,git reflog为空),就可以通过git prune清理了
      # git prune 清理未被关联的对象,释放空间

    31.git reflog expire --all 让90天前的reflog过期
      git reflog expire --expire=now --all

    32.git rerere gc对合并冲突的历史记录进行过期操作

    33.git管家
      git gc --prune=now :立即删除非关联的对象,--prune=now会传送个git reflog expire --expire=now,否则2周后清理
      git gc: 会对关联的对象进行增量存储,会对非关联的对象变为松散存储

    34.git init --bare创建的没有工作区(直接就是.git下的内容)的版本库也可以使用git log等命令

    35.git pull : 先拉下来,然后再与本地提交进行合并,合并的先后顺序应该是由提交顺序决定的。

    36.git ls-files -s 合并冲突时来看,第三个字段只有在冲突时才会大于0,会看到冲突文件的三个副本
      git show :1:README 显示双方冲突的祖先版本
      git show :2:README 显示当前冲突文件在当前分支中修改的副本
      git show :3:README 显示当前冲突文件在合并分支中修改的副本
      也可以使用git mergetool 但是没感觉它好用

    37.merge冲突解决
    1.修改了相同文件的相同地方产生git merge冲突,先手动编辑冲突文件的冲突区域并去掉冲突标识符,再git add,再commit
    就是合并提交。

    2.合并的分支都对同一文件重命了不同的名字产生git merge冲突,删除掉一个冲突文件,再提交即可实现merge 提交

    3.git config merge.conflictstyle diff3 、merge(默认)更改默认的文件内容冲突标识,注意没有等号!

    38.git打补丁

    1.已经提交
    获取补丁:git format-patch -1
    打补丁: git apply 0001-2.patch
    也可以迁出操作,获取历史提交的补丁

    2.未提交
    git diff master > 000-patch
    将master分支上相对于当前提交的所有提交打成一个名为000-patch的patch

    回退一次提交打完这次提交的补丁后还能merge
    打patch后再修改文件后patch就打不成功了(应该是index变了),文件内容改回去后又可以了!
    git diff 2test.c后就可以直接切换分支了,而不用commit!再checkout回去,git diff --cached发现暂存区已经被覆盖了

    3.使用commit-id打补丁
    git diff acb8cd15() 4ff35d80() > 0000-patch
    生成了一个000-patch,使用 git apply进行打补丁。

    git diff old_hash new_hash > diff.patch 查看两次提交之间的变化,注意后面的是最新的提交。

    使用 git format-patch -1 new_hash old_hash 不行

    使用# git format-patch -1 AudioPolicyManager.cpp 来取出某一个补丁中只与某个文件有关的补丁。 

    39.git rm --cached file_path_name 删除暂存区中的文件(git add时多添加了可以使用)

    40.只恢复一个文件: $ git checkout -- filename
    这条命令把hello.rb从HEAD中签出并且把它恢复成未修改时的样子.

    41.git revert 是撤销某次操作,此次操作之前和之后的commit都会被保留,并且会把这次撤销作为一次最新的提交;
    git revert HEAD 撤销前一次 commit
    git revert HEAD^ 撤销前前一次 commit
    git revert commit-id 撤销指定的版本,撤销也会作为一次提交进行保存。git revert是提交一个新的版本,将需要revert的版本的内容再反向修改回去,
    版本会递增,不影响之前提交的内容。
    git reset 是撤销某次提交,但是此次之后的修改都会被退回到暂存区;
    git reset是还原到指定的版本上,这将扔掉指定版本之后的版本

    42.交互式变基
    git rebase -i ommit_id进行交互式变基,修改交互时的message信息即可实现修改ID、修改提交顺序的目的(rebase到自己分支之前的状态)

    ①交互式变基后在repo sync代码后可能会出现:
    error: source/linux/: prior sync failed; rebase still in progress
    解决:
    git rebase --abort
    git am --abort(可能不需要)

    ②git merge来合并所看到的commit的顺序是按时间的先后顺序的,git rebase来合并所看到的commit的顺序不是。
    ③git pull --rebase,这里表示把你的本地当前分支里的每个提交(commit)取消掉,并且把它们临时保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后
    把本地当前分支更新为最新的"origin"分支,最后把保存的这些补丁应用到本地当前分支上。

    43.检出某个分支中的某个文件

    [ubuntu @linux]$git checkout topic/rvc drivers/media/i2c/scxx.c 加的是文件的路径名
    [ubuntu @i2c]$ git checkout topic/rvc_v3.4 sc00.c

    45.只查看某个人的提交记录:[ubuntu @linux]$ git log --author="Jinda Fu"

    git log --committer=xxxx 也是只看某个人的提交

    46. git cherry-pick --continue cherry-pick解决冲突后继续cherry-pick

       git cherry-pick --abort 取消cherry-pick操作。

    47. git add directory -A 将这个目录中的说有修改全部提交,包括删除的和新增的

    48.查看两个tag之间的提交

    $ git log --pretty=oneline tag1...tag2 --pretty=oneline打印出完整的hash
    34ba8419b037f8fc018d554db641806c4abcdae6 Merge branch 'topic/sd-reader' into 'master'

    $ git log --oneline tag1...tag2 --oneline只打印出部分hash
    34ba841 Merge branch 'topic/sd-reader' into 'master'

    49. git设置别名
    $ git config --global alias.br branch
    $ git config --global alias.li "log --oneline"
    --global的修改会体现在~/.gitconfig文件中(若不加--global是.git/config),也可以直接修改这个文件进行git配置。

    50. 要查看远程库的信息,用git remote, -v显示更详细的信息

    51.查看git版本库位置

        strace -e 'trace=file' git status      // 追踪git status的磁盘访问
     git rev-parse --show-toplevel       // 显示工作区根目录
     git rev-parse --git-dir                    // 显示版本库.git目录所在位置
        git rev-parse --show-prefix          // 相对于工作区根目录的相对目录
       git rev-parse --show-cdup            // 从当前目录后退到工作区的深度
    在git工作区的某个子目录下执行操作时,会在工作区目录中依次向上递归查找.git目录,找到的.git目录就是工作区对应的版本库,.git所在目录就是工作区的根目录,文件.git/index记录了工作区文件
    的状态(实际上是暂存区的状态)。

    52. 查看某个提交修改了哪些文件  

    git log -3 --stat  查看最近三次提交每次修改的文件

    git log hash_id --stat -1  查看某一次提交修改的文件

    53. 给 git commit 信息加一个模板

    # cat ~/.git_log_message
    This is test,log is: 
    
    # git config --global commit.template  ~/.git_log_message //将这个模板配置到git中
    
    # git commit    //提交后就可以在这个模板上修改log信息了

    # git log --pretty='%an %cn 以看到author和committer

    54. 查看某个提交在哪个分支上

    git branch -r --contains <commit_id>

    55. git只克隆repo仓库中的某一个版本库

    $ cat ./repo/projects/android/kernel/configs.git/config
    [remote "origin"]
    url = ssh://xxxxxxxxxx/kernel/configs
    review = http://gerrit.xxxxxxx

    $ git clone ssh://xxxxxxxxxx/kernel/configs

    repo只拉取一个仓库:

    repo init -u ssh://gerrit.xxxx -b <breach name> -m <xml文件> //只拉取.repo仓库

    repo sync -c <仓库名> //fetch下来git仓库,xml文件中project name=<仓库名>

    56.删除分支 

    删除服务器远端的分支:

    git push origin –delete 分支名

    如果是要删除本地已经合并了的分支:

    git branch –d 分支名

    删除本地未合并的分支:

    git branch –D 分支名

    二、使用git打补丁

    1.检测补丁有无问题
    $ git apply --check xxx.patch

    2. error: xxxxx: patch does not apply
    出现这种一般会是补丁冲突,这种一般是强制打上补丁(使用--reject)后根据产生的*.rej文件来手动解决冲突。

    3. warning: xxxx.c has type 100644, expected 100755
    出现这种警告一般是文件内没有冲突,但是文件的权限发生变动。一般没有影响。

    4.强制打补丁
    $ git apply --reject xxx.patch
    然后再手动修改冲突,find ./ -name *.rej找到这些冲突的补丁,手动打上

    5.git am同样有--reject选项,添加这个选项可以将能打上的补丁先打上,冲突的文件生成*.rej文件。

    39.分支变基
    1.可以checkout out很久以前的提交,然后git checkout -b sfl创建新分支,gitg会发下它很靠后,然后
    git rebase master就发现它骑在了master分支的头上,然后commit一次发现在master头上有一次提交

    40.本地分支分支重命名
    git branch -m old_local_branch_name new_local_branch_name

    41.远程分支操作:
    1.$ git branch -a :查仓库的所有分支,包括远程分支。

    2.$ git push origin --delete <branchName> : 删除远程分支
    或者$ git push origin :<branchName> : 推送一个空分支到远程分支,其实就相当于删除远程分支

    3.$ git push origin --delete tag <tagname> : 删除远程分支的tag

    4.git tag -d <tagname> : 应该是删除本地tag
    git push origin :refs/tags/<tagname> 推送一个空tag到远程tag,也就达到了删除远程分支的tag的效果

    5.$ git remote show origin : 查看远程分支的状态

    6.$ git remote prune origin : 若此分支对应的远程分支已经被删除,使用它来将本地对应分支从本地版本库中去除

    7.重命名远程分支 :其实就是先删除远程分支,然后重命名本地分支,再重新提交一个远程分支。eg.将devel分支重命名为develop分支
    git branch -av 查看分支
    git push --delete origin devel 删除devel分支
    git branch -m devel develop 重命名本地分支
    git push origin develop 推送本地分支

    8.$ git push --tags : 推送本地tags

    9.$ git fetch origin tag <tagname> : 获取远程tag
    参考:
    https://makandracards.com/makandra/621-git-delete-a-branch-local-or-remote
    https://blog.zengrong.net/post/1746.html

     42.合并服务器上的代码

    创建一个本地master分支: git branch master, git checkout master
    reset到远程服务器上的master分支:git reset --hard origin/master
    将远程的update分支merge到master分支: git merge origin/topic/update --no-ff (--no-ff:创建合并提交)
    将本地的master分支推送到远程服务器:git push origin master:master
    查看验证:git fetch -p gitg &

    将master分支merge到项目分支:
    git merge master --no-ff
    git push origin g8s/master:g8s/master

    43.在历史提交中快速查找iperf相关提交
    $ git log --oneline | grep iperf

    44.增加签名: git commit -s -m "commit message"   -s签的是自己的名字

    45.使用git am来保留patch作者的信息

    patch -p1 < 0001--JFFS2-community-fix-with-not-use-OOB.patch
    这样来打patch,但是这样会把这些有用的信息丢失。由于这些patch显然是用git format-patch来生成的,所以用git的工具应该就可以很好的做好。

    git -am 可以保留这些信息。
    在使用git -am之前,你要首先git am –abort 一次,来放弃掉以前的am信息,这样才可以进行一次全新的am。
    不然会遇到这样的错误: .git/rebase-apply still exists but mbox given.

    git-am 可以一次合并一个文件,或者一个目录下所有的patch,或者你的邮箱目录下的patch.

    git am XXX/*.patch 将XXX目录下的所有patch打上去,这里git就会按照文件名的顺序一次am这些patch
    git am *.patch

    git am 和 git apply的区别: git am不需要再提交一次,而git apply打完补丁后需要从新提交一次。

    在解决完冲突以后,可以用git add来让git知道你已经解决完冲突了。
    可以运行git am –abort,撤销整个am的东西
    如果忽略某一个patch,可以运行git am –skip来跳过这个patch.

    46.$ git log --author=Li.ming  查看某一个人的提交,注意是.而不是,

    $ git log origin/g6s/master --author=Xiao.liang

    47. .git/config文件中有版本库的网址等信息

    48. 将缓存的文件删除

    $ git rm –cached "文件路径" 不删除物理文件,不修改物理文件的内容,仅将该文件从缓存中删除;

    $ git rm –f "文件路径" 不仅将该文件从缓存中删除,还会将物理文件删除

    49. 若是想提交删除一个文件的提交:

    $ git rm -rf xxxx.c
    $ git commit

    50. 查看一个版本库在服务器上的位置和主分支
    $ git rev-parse --git-dir //查看到.git版本库的位置
    $ cat .git/config

    ......
    [remote "origin"]
    url = ssh://gerrit.scq.abc.com:14562/platform/vendor/lk    //版本库在服务器上的位置: platform/vendor/lk
    projectname = platform/vendor/lk    
    [branch "master/Q/SM8210"]    //服务器上的分支,就是拉下来时的分支。若是断头的,就没有分支信息
    remote = origin
    merge = refs/heads/master/Q/SM8210

     51.git常用alias配置

    sun@ubuntu:~/$ cat ~/.gitconfig 
    [user]
            name = xxx
            email = xxx@xxx.com
    [alias]
            st = status
            ci = commit
            st = status    
            co = checkout
            ci = commit
            br = branch
            lo = log --oneline
            la = log --author
            lg = log --graph
            dir = rev-parse --git-dir
    [commit]
    [core]
            editor = vim
    [color]
            ui = auto
    [push]
            default = matching

    52. .git/config文件

    $ cat .git/config 
    ...
    [remote "origin"]
            projectname = kernel/msm-4.19 //git仓库的名字
    ...

    git使用小技巧:

    1.git log:
        git log --oneline ./ 只看当前目录下的所有文件的提交记录
        git log --oneline app_test.c 只看与app_test.c相关的提交
        git log --oneline --graph ./ 对当前目录下的文件的提交以graphic的形式看


    二、本地git配置
    1.使git带颜色显示
    git config --global color.ui true
    2.git命令自动补全
    需要在/etc/profile和~/.bashrc中添加
    if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
    fi
    但是最好不要添加,会导致Ubuntu无法登陆,将其单独写成一个脚本使用时执行一次。
    由此导致无法登陆解决方法:
    ctrl + alt + F1进入命令终端,然后删除更改。
    3.禁止非快进试推送
    git [--git-dir=/path/to/xxx.git] config receive.denyNonFastForwards true


    3.三级配置
    git config -e :修改此git仓库配置.git/config,显示如下
    [core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    [remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = git@gitlab.com:TYTHT/bmp.git
    [branch "master"]
    remote = origin
    merge = refs/heads/master

    git config -e --global :修改针对此用户的git仓库配置~/gitconfig,显示如下
    [color]
    ui = true
    [user]
    name = pinctl
    email = 2634520619@qq.com

    git config -e --system :修改针对此系统的git仓库配置的/etc/gitconfig,里面暂时为空

     三、在github上创建版本库

    GitHub 是一个网站,它提供 Git 仓库托管服务的。 只要注册一个 GitHub 账号,就可以免费获得 Git 远程仓库。
    对于第 1 次使用 GitHub,需要:
    (1) 创建 SSH Key:$ ssh-keygen -t rsa -C "your email"
    (2) 注册 GitHub 用户:登录 https://github.com/ 注册账户
    (3) 在 GitHub 里添加 SSH Key:点击网页右上角的按钮,选择“Settings”, 将第一步生成的~/.ssh/id_rsa.pub内容添加到Key栏后点击“Add Key”
    (4) 创建仓库:点击网页右上角的“+”号,选择“New repository”:

    GitHub 需要SSH Key的原因是要识别出你推送的提交确实是你推送的,而不是别人冒充的,而 Git 支持 SSH 协议,所以, GitHub 只要知道了你的公钥,就可以确认
    只有你自己才能推送。

    GitHub 允许你添加多个 Key。假定你有若干电脑,你一会儿在公司提交,一会儿在家里提交,只要把每台电脑的 Key 都添加到 GitHub,就可以在每台电脑上往 GitHub 推送了。

    在 GitHub 上免费托管的 Git 仓库,任何人都可以看到喔(但只有你自己才能改)。

    (5) 添加文件并推送到版本库
    git init
    git add README.md
    git commit -m "first commit"
    git remote add origin https://github.com/xxxx/Android_work.git
    git push -u origin master

    (6)下载和查看源码
    a.可以直接在版本库的网址上查看源码
    b.下载:git clone https://github.com/xxxx/Android_work.git

    四、总结
    1.每次git commit,工作区必须是干净的(即所有修改都已经git add; 是工作区,不是暂存区)
    2.分支名如果不像这样topic/msater,而是一个简单的名字的话,就算是有分支,好像还是在master分支之上。
    3.gitg是从最新更改开始画图,git log是从HEAD开始打印,gitg显示的select branch就是没有分支名的迁出分支
    4.git checkout和git reset不同,前者是迁出,HEAD指向并没有变,后者HEAD变了。
    5.mv针对工作区的修改 git mv是针对暂存区的修改
    6.暂存区变了就可以使用git commit, 而没有必要非要先git add等操作
    7.gitg也可以完成commit功能!
    8.修改相同文件的不同地方merge时不会产生冲突,相同地方会产生冲突。

    五、问题

    1. 使用Yocto 编译新BSP的时候可以把build/tmp目录下的所有文件删除,若还是不行,可以把下面两个目录下的*.done文件全部删除,然后重新编译即可。
    build/downloads/
    build/downloads/git2

    六、优秀资源链接

    1.廖雪峰git教程

    https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001374385852170d9c7adf13c30429b9660d0eb689dd43a000

    七、git图形化显示

    1.支持图形显示的话可以使用gitg/qgit工具。

    2.不支持图形显示的话,可以使用git  log --graph显示。

  • 相关阅读:
    委托(delegate)的三种调用方式:同步调用,异步调用,异步回调(转载)
    C#异步:实现一个最简单的异步
    关于Thread.IsBackground属性的理解(转载)
    C# 中的多线程(转载)
    个人对AutoResetEvent和ManualResetEvent的理解(转载)
    C#线程系列讲座(4):同步与死锁
    Nginx location 配置踩坑过程分享
    微信扫码登录网页实现原理
    负载均衡SLB
    Tomcat学习
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/8152056.html
Copyright © 2011-2022 走看看