• 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显示。

  • 相关阅读:
    【NOIP2007】守望者的逃离
    20200321(ABC)题解 by 马鸿儒 孙晨曦
    20200320(ABC)题解 by 王一帆
    20200319(ABC)题解 by 王一帆 梁延杰 丁智辰
    20200314(ABC)题解 by 董国梁 蒋丽君 章思航
    20200309(ABC)题解 by 梁延杰
    20200307(DEF)题解 by 孙晨曦
    20200306(ABC)题解 by 孙晨曦
    20200305(DEF)题解 by 孙晨曦
    20200303(ABC)题解 by 王锐,董国梁
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/8152056.html
Copyright © 2020-2023  润新知