git 使用指导

    xiaoxiao2021-03-25  104

    使用篇 1. 我们使用的分支    目前创建了一个ACL_XXX_DEV分支此分支进行开发 2. 查看日志和差异(git log & git diff)    针对下图                      A---B---C ACL_XXX_DEV                     /                D---E---F---G remotes/origin/ACL_XXX_DEV     查看两个分支有没有交点         git merge-base ACL_XXX_DEV remotes/origin/ACL_XXX_DEV     上面执行的结果是 E ,后面可以根据该点进行log或rebase操作;     git log  /*当前分支日志*/     git log -N /*查看最近N次的LOG日志*/     git log <branchName> /*其他分支日志*/     git log --pretty=oneline --graph  /*--pretty=oneline 只有一行, --graph 表示分支历史简单图示*/     git log --grep=xxx  /*log日志中包含xxx的日志显示*/          显示从上游分支remotes/origin/ACL_XXX_DEV到ACL_XXX_DEV分支的提交log,     git log remotes/origin/ACL_XXX_DEV..ACL_XXX_DEV     git log E..C         也就是A B C的log,如果当前分支是ACL_XXX_DEV,那么这个分支名称可以省略     另外ACL_XXX_DEV可以用C hash值替代,remotes/origin/ACL_XXX_DEV 可以用E A^ A~ 替代,效果是一样的     A^表示A接到的第一父亲 A^2表示第2父亲,在上图中是没有的,一般在分支merge的时候会出现,A~表示A的父亲,A~2表示父亲的父亲,即D      git diff E ACL_XXX_DEV --stat /*查看 A B C的修改统计 */      除了--stat 还有 --name-status等其他选项,可以git help diff看下      git diff A^ A --stat 查看A提交点做了哪些修改      如果要看具体的,可以通过difftool(内部使用了vimdiff,在设置篇中设置的)      git difftool A^ A      如果两个差异比较大,可以指定某个文件的差异      git difftool A^ A -- code/.../xxx.file 3. git的分支操作:    1) 创建分支: git checkout -b <branchName> [<start-point>] ,创建一个本地的开发分支,这个分支的HEAD指向start-point,并检出。       例如创建一个ACL_TOPA的分支,检出点和ACL_XXX_DEV的HEAD一样,并且切换到ACL_TOPA分支       git co -b ACL_TOPA ACL_XXX_DEV                 (从本地分支ACL_XXX_DEV检出)       git co -b ACL_TOPA remotes/origin/ACL_XXX_DEV  (从远端分支ACL_XXX_DEV检出)       上面的只是从一个分支提交点检出分支,并没有建立跟踪关系,如要建立跟踪关系,则需要加 --track参数,这样后面可以直接push和pull       git co -b ACL_TOPA remotes/origin/ACL_XXX_DEV --track       加了--track参数的,可以通过git config --list看到有一项  branch.ACL_TOPA.merge=refs/heads/ACL_XXX_DEV       如果是同名的,则不用加--track参数,也可以进行跟踪,直接进行push 和pull操作    2) 切换分支: git checkout <branchName>       git co ACL_TOPA       本地的文件将切换到该分支下;    3) 分支共享: git push origin <branchName>.           git push origin ACL_XXX_DEV 可以将dev分支的修改推送到服务器。 如果服务器上没有该分支,该命令可以在服务器上新建一个分支。         在远端服务器上(10.42.119.8)会多了一个ACL_XXX_DEV的共享分支         在本地也会多了一个remotes/origin/ACL_XXX_DEV的远端分支    4) 分支删除:         a. 删除本地的特性分支,执行git branch -d <branchName>   或  git branch -D <branchName>         b. 将共享到远端的特性分支删除  git push origin :<branchName>         C. 如果本地的远端分支如remotes/origin/ACL_XXX_TMP分支需要删除,git branch -d -r origin/ACL_XXX_TMP 省略了remotes参数                    批量删除远端分支 git br -r | grep 3.00.30_B | xargs git br -d -r    5) 拉取分支的变更,这个只会更新到本地的远端库,不会将变更影响到远端库的本地分支。         例如 git fetch origin refs/remotes/*:refs/remotes/* 会将远端库origin下面的分支refs/remotes/* 更新到本地库中refs/remotes/*分支       使用缩略关键字       git fch       一些团队内部推送上去的分支,一般没有前缀,拉取不了更新,使用get fetch拉取       git fetch       比如共享的ACL_XXX_DEV分支会将更新到本地的remotes/origin/ACL_XXX_DEV 远端分支,但是不会影响本地ACL_XXX_DEV分支;       执行前                      A---B---C ACL_XXX_DEV                     /                D---E---F---G remotes/origin/ACL_XXX_DEV       执行后,更新了远端的H I提交                      A---B---C ACL_XXX_DEV                     /                D---E---F---G---H---I remotes/origin/ACL_XXX_DEV       git update           新建git update命令,省去反复敲上面两个命令的麻烦。           在/usr/local/bin/下面新建文件"git-update",将git fch、git fetch两个命令添加到文件中,命令以回车分隔(也就是一个命令一行)。           修改该文件权限 chmod 777 /usr/local/bin/git-update。    6)拉取分支的变更,并更新到本地分支;       上面checkout的时候已经加了--track参数,那么是可以直接pull的,例如先切换到ACL_XXX_DEV本地分支,然后从远端共享库remotes/origin/ACL_XXX_DEV       拉取更新并合入到本地ACL_XXX_DEV本地分支;       git co ACL_XXX_DEV       git pull --rebase       --rebase选项,为了保持分支提交历史的线性;       执行前                      A---B---C ACL_XXX_DEV                     /                D---E---F---G remotes/origin/ACL_XXX_DEV       执行后,更新了远端的H I提交                                     remotes/origin/ACL_XXX_DEV                                    /                D---E---F---G---H---I---A'---B'---C' ACL_XXX_DEV       如果拉取失败,可以使用git mergetool或windows下的冲突解决工具来解决    7)推送本地更新到远端共享库供其他小伙伴使用;       git co ACL_XXX_DEV       modify...       commit...       自己的本地分支不能保证已经包含共享库上的更新,因此在推送前要先更新到本地分支上来;       git pull --rebase       git push       如果没有跟踪的分支,可以指定到某个分支git push origin ACL_XXX_DEV              还是前面的例子,在pull的基础上,push的结果如下,本地分支和本地远端分支指向同一个位置;                D---E---F---G---H---I---A'---B'---C' ACL_XXX_DEV (remotes/origin/ACL_XXX_DEV)                    8)分支変基,git rebase [--onto <newbase>]  [<upstream>] [<branch>]            比如将ACL_TOPA上的一段提交移到ACL_XXX_DEV分支上重做一遍;      git co ACL_TOPA      modify...      commit...      下面几种命令格式达到的效果是一样的;      git rebase --onto ACL_XXX_DEV  ACL_XXX_DEV ACL_TOPA      git rebase --onto ACL_XXX_DEV  ACL_XXX_DEV            /*当前分支的名称可以省略,如果rebase的不是当前分支,则不能省略*/      git rebase --onto ACL_XXX_DEV  E ACL_TOPA             /*上游分支可以有很多表示方法 A^ A~也是可以的*/      执行前                      A---B---C ACL_TOPA                     /                D---E---F---G ACL_XXX_DEV      执行后                              A'--B'--C' ACL_TOPA                             /                D---E---F---G ACL_XXX_DEV     这样可以将改动合入到ACL_XXX_DEV分支,但是ACL_XXX_DEV还是在原来的位置,如果要变动ACL_XXX_DEV头结点位置,     上面是一个线性历史提交,因此可以直接使用merge进行分支合并,这种方式叫fast-forward方式;     git co ACL_XXX_DEV     git merge ACL_TOPA     merge后,两个分支指向同一个结点     D---E---F---G---A'---B'---C' (ACL_TOPA)ACL_XXX_DEV     后面也可以用push将A B C内容推送给到共享库          使用rebase -i选项修改提交节点顺序:     例如:A---B---C---D1---E1---D2---E2---D3---E3     需要将D1,D2,D3修改放在一起,E1,E2,E3修改放在一起,可以执行 git rebase -i C     然后在出现的编辑器中修改提交点顺序,放在最上面的提交点为时间最早的提交,最下面的提交点为时间最晚的提交。保存然后关闭。     修改后效果:A---B---C---D1---D2---D3---E1---E2---E3          使用rebase -i同样可以将非线性的分支修改为线性的分支。     例如:A---B---C---D1---D2---D3---M                      \              /                       \E1---E2---E3/     执行后效果:A---B---C---D1---D2---D3---E1---E2---E3         9) git cherry-pick操作     上面的例子,也可以这样实现:     git co ACL_XXX_DEV     git cherry-pick A B C          执行前                      A---B---C ACL_TOPA                     /                D---E---F---G ACL_XXX_DEV      执行后                      A---B---C ACL_TOPA                     /                D---E---F---G---A'---B'---C' ACL_XXX_DEV     更复杂的可以结合git rev-list来进行; 4. git本地操作:   1)将修改暂存: git add [-u] <path> , <path>可以是目录,也可以是文件,如果是目录,则迭代添加该目录下所有修改的文件。     如果使用-u选项,则只添加修改的文件,新增的文件不会被添加   2)将修改提交到本地仓库: git commit -m <msg>, 该命令将暂存区域的修改提交到本地仓库。如果是提交某个需求的修改,      要求<msg>格式为 "<EC/RCS单号:故障/需求描述>:修改描述".   3)丢弃本地的修改: git checkout -- <path>, <path>可以是目录,也可以是文件,如果是目录,则迭代丢弃该目录下所有文件的修改      现在版本全编或xml make的时候,会自动修改一些受控文件,这些文件可以用git checkout -- . 来把当前目录所有的文件进行恢复      主要执行前,确保不包含自己未提交的东西(git update-index也可以忽略受控文件的修改,但是在git stash和git checkout的时候操作会有点麻烦)   4)取消已经暂存的修改:git reset HEAD <path>, <path>可以是目录,也可以是文件,如果是目录,则迭代取消该目录下所有在暂存区文件的修改   5)如果本地有修改还未提交,但是现在不想提交,想切换到其他分支处理一些事情,处理完成后再回来继续做     git stash     /*将当前未提交的工作区和暂存区压栈*/     git co ...     ...     git stash pop /*会将栈中保存的修改恢复,同时在栈中删除*/          git stash list /*    会显示栈中的保存的修改,一般像下面的样子*/     stash@{0}: WIP on ACL_XXX_DEV: 0f8f2e5 #&#XXX LOG          git stash apply stash@{0} /*不删除栈中的修改,应用保存的修改*/     git diff stash@{0} [ACL_XXX_DEV] /*看下栈中保存的与当前工作目录中的差异 ,也可以加分支名称,也可以用difftool看具体修改*/    6) 将工作代码切换到之前某个提交点(同时当前分支指针也指向了这个提交点)     git reset <commit-hash>   /*默认模式是mixed mode,即暂存区会恢复到这个提交,但是工作区不会恢复,因此git status可以看到相对这个提交点的所有提交*/     git reset --hard <commit-hash> /*hard mode,会将暂存区和工作目录全部恢复到那个提交点*/     git reset --soft <commit-hash> /*soft mode 暂存区和工作目录都不会恢复到那个提交点*/     如果将某个提交点的文件检出来     git co <commit-hash> -- code/.../filename    /*该命令会覆盖当前提交的点的文件*/     git show <commit-hash>:code/.../filename > code/.../filename_xxx   /*可以保存为别名,此方法用于在某些场合,使用工具对某些非文本文件格式的打开、对比等操作*/   6)清理工作目录     git co -- .    /*makeday或xmlmake会修改受控的文件,这个可以恢复下,见本章节3)部分*/     git clean -df  /*强制删除un-tracked file,但是.gitignore中指定的文件不会被删除,这个命令可用于解决完冲突、编译完,删除非跟踪文件*/     git cleanall   /*这个做了个别名,实际上是git clean  -dfx -e .gitignore -e klocwork/ ,包括.gitignore中的指定的文件也会被删除,但是-e指定的文件不会被删除                     这个命令可用于切换大版本,需要将所有的文件删除,但是保留.gitignore文件和klocwork文件*/ 5. 使用git生成补丁   git log --grep=<需求名称> --author=chupenghong -p --binary --reverse >patch,其中--grep用于过滤某个需求提交到log中的标记名称, --author用于指明提交的作者 -p生成补丁格式  --binary对二进制文件生成补丁 --reverse 按时时间顺序反转   git apply [--check | --reject | --stat | --ignore-whitespace] patchfile 可以在任意目录下应用补丁,--check检查哪些文件打补丁会失败,--reject会在补丁应用失败时生成.rej文件以表明哪些文本块失败了,--stat可以查看补丁中包含哪些文件的修改                                                                                                     --ignore-whitespace 打补丁时忽略空格,一般在提交打补丁命令时最好加上该选项                                                                                                      6. git svn的使用 (参考《git权威指南》 26.4节,我们涉及到更新所有分支的权限问题,实现和这个书上讲的不一致)      svn副本库的导入就不在赘述,下面讲下如何从git库提交代码到svn   1. 在10.42.119.8的/home/git/rosngdev 目录 执行git svn fetch 从svn上拉取最新更新到共享库          然后在本地机器上执行      git fch (实际上是git fetch  origin refs/remotes/*:refs/remotes/*) 从共享库获取更新到本地库      (目前119.8上每一分钟自动git svn fetch一次,一般不需要大家登陆到119.8再执行了,除非点子背一点。。。)   2. git co -b tmp_ci xxx 创建一个临时分支tmp_ci用于提交,这个临时分支包含你要提交的一些修改   3. rebase合入rosng_dev分支,在rosng_dev分支上将修改重新做一遍,此时也可以将不想提交的的commit去掉;      upstream 可以是非同源的      git rebase –onto rosng_dev <up_stream> [<branchname>]      如果出现冲突可以使用git mergetool或windows上的工具来解决冲突,解决冲突后,      git add 冲突的文件      git rebase --continue   4. git reset rosng_dev 此处默认使用的--mixed选项,的目的是将HEAD和index暂存区重置,而工作目录的修改保持,      这样可以给我们一个机会,对那些受控的文件进行剔除,可以用git checkout -- <file>命令;      另外一个原因是将多个提交点压缩成一个提交点;   5. git ci -am "<EC/RCS单号:故障/需求描述>:修改描述" 剔除后受控文件后,然后进行提交到tmp_ci分支   6. 如果修改可能持续一段时间,此时再次获取最新更新     (目前119.8上每一分钟自动git svn fetch一次,一般不需要大家登陆到119.8再执行了,除非点子背一点。。。)      10.42.119.8的/home/git/rosngdev 执行      git svn fetch      本地机器      git fch   7. git svn dcommit 提交修改到svn   9. 执行成功后,如果有受控的文件,那么需要将受控文件手动再修改下;   10. git br -d tmp_ci   另外一种提交方法:   1. 拉取更新同上   2. git co -b tmp_ci rosng_dev 从rosng_dev分支创建一个临时分支   3. git cherry-pick <commit-A> <commit-B> ... 将要合入的提交点以此挑拣过来,如果有多个的话,肯能冲突会多一点      如果提交点不连续,可以用此方法,也可以结合标准git提交列表git rev-list使用,例如将相同rcs编号xxx的所有提交点都挑拣过来      git rev-list --reverse <branch> --grep=xxx | git cherry-pick --stdin      git rev-list --reverse upstream..<branch> --grep=xxx | git cherry-pick --stdin      --reverse 提交逆序排列,可按合入顺序排序 来理解   4. git reset rosng_dev 后面的步骤和上面的相同   备注:无论是rebase还是cherry-pick,你都可以在提交svn前,准备很长时间,当然这不会影响别人合入svn,也无需锁文件         如果你想在合入svn时冲突少一点,那么可以提前将提交点压缩成一个点,这样可以减少冲突次数 其他技巧拾遗: 1)    git log 默认使用less工具查看日志, less启用了长行截断模式,在日志的一行较长时会被截断。关闭长行截断,可以设置export LESS=FRX. 该设置可放到.bashrc文件中。
    转载请注明原文地址: https://ju.6miu.com/read-5285.html

    最新回复(0)