Git

本文编辑整理自:http://guibin.iteye.com/blog/1014369
http://hi.baidu.com/tiger_tnt/blog/item/a0464ffa6a8115d9b58f314d.html
http://web.mit.edu/~mkgray/project/silk/root/afs/sipb/project/git/git-doc/git-reset.html
一、基本篇
在git的一般使用中,如果发现错误的将不想staging的文件add进入index之后,想回退取消,则可以使用命令:git reset HEAD <file>...,同时git add完毕之后,git也会做相应的提示,比如:
引用

# Changes to be committed: 
#   (use "git reset HEAD <file>..." to unstage) 
# new file:   Test.scala 

git reset [ --hard|soft|mixed|merge|keep]  [<commit> HEAD]:将当前的分支重设(reset)到指定的<commit>或者HEAD(默认,如果不显示指定commit,默认是HEAD,即最新的一次提交),并且根据[mode]有可能更新index和working directory。mode的取值可以是 hard、soft、mixed、merged、keep。下面来详细说明每种模式的意义和效果。
A).  --hard:重设(reset) index和working directory,自从<commit>以来在working directory中的任何改变都被丢弃,并把HEAD指向<commit>。 
具体一个例子,假设有三个commit, git st:

commit3: add test3.c
commit2: add test2.c
commit1: add test1.c

执行git reset --hard HEAD~1后,
显示:HEAD is now at commit2,运行git log

commit2: add test2.c
commit1: add test1.c

运行git st, 没有任何变化
B)--soft:index和working directory中的内容不作任何改变,仅仅把HEAD指向<commit>。这个模式的效果是,执行完毕后,自从<commit>以来的所有改变都会显示在git status的"Changes to be committed"中。 
具体一个例子,假设有三个commit, git st:

commit3: add test3.c
commit2: add test2.c
commit1: add test1.c

执行git reset --soft(默认) HEAD~1后,运行git log

commit2: add test2.c
commit1: add test1.c

运行git status, 则test3.c处于暂存区,处于准备提交状态。即此时git commit就会提交它。
  在使用git进行协作开发时,我们经常需要将自己的修改生成patch发给被人,但是在修改代码的过程中我们进行了很多次的提交,如何生成从最初的代码状态到最终代码状态的patch呢?下面要介绍的功能是应对这中情况。
现假设我们git软件仓库中的分支情况如下:
a-->b-->c
也就是说我们的代码从状态a修改到状态b,进行一次提交,然后再修改到状态c,进行一次提交。这时我们已经肯定由a到c的修改是正确的,不再需要状态b了,并且要把从a到c的变化生成一个patch发送给别人。如果直接打包的话会生成两个path,那么如何生成一个patch呢,这时就需要git-reset命令。
首先给状态a创建一个tag,假设名称为A,然后执行
git-reset --soft A
这样我们的软件仓库就变为
a
状态b和状态c都已经被删除了,但是当前的代码并没有被改变,还是状态c的代码,这时我们做一次提交,软件仓库变成下面的样子:
a-->d
状态d和状态c所对应的代码是完全相同的,只是名字不同。现在就可以生成一个patch打包发给别人了
C)--mixed:仅reset index,但是不reset working directory。这个模式是默认模式,即当不显示告知git reset模式时,会使用mixed模式。这个模式的效果是,working directory中文件的修改都会被保留,不会丢弃, 但是也不会被标记成"Changes to be committed",但是会打出什么还未被更新的报告。报告如下: 
引用
Unstaged changes after reset: 
M Test.Scala 
M test.txt

D)--merge--keep用的不多,在下面的例子中说明。 
二、常用示例
下面列出一些git reset的典型的应用场景: 
A) 回滚add操纵 
引用
$ edit                                     (1) 
$ git add frotz.c filfre.c 
$ mailx                                    (2) 
$ git reset                                (3) 
$ git pull git://info.example.com/ nitfol  (4) 

(1) 编辑文件frotz.c, filfre.c,做了些更改,并把更改添加到了index 
(2) 查看邮件,发现某人要你pull,有一些改变需要你merge下来 
(3) 然而,你已经把index搞乱了,因为index同HEAD commit不匹配了,但是你知道,即将pull的东西不会影响已经修改的frotz.c和filfre.c,因此你可以revert这两个文件的改变。revert后,那些改变应该依旧在working directory中,因此执行git reset。 
(4) 然后,执行了pull之后,自动merge,frotz.c和filfre.c这些改变依然在working directory中。 

B) 回滚最近一次commit 
引用
$ git commit ... 
$ git reset --soft HEAD^      (1) 
$ edit                        (2) 
$ git commit -a -c ORIG_HEAD  (3) 

(1) 当提交了之后,你又发现代码没有提交完整,或者你想重新编辑一下提交的comment,执行git reset --soft HEAD^,让working tree还跟reset之前一样,不作任何改变。 
HEAD^指向HEAD之前最近的一次commit。 
(2) 对working tree下的文件做修改 
(3) 然后使用reset之前那次commit的注释、作者、日期等信息重新提交。注意,当执行git reset命令时,git会把老的HEAD拷贝到文件.git/ORIG_HEAD中,在命令中可以使用ORIG_HEAD引用这个commit。commit 命令中 -a 参数的意思是告诉git,自动把所有修改的和删除的文件都放进stage area,未被git跟踪的新建的文件不受影响。commit命令中-c <commit> 或者 -C <commit>意思是拿已经提交的commit对象中的信息(作者,提交者,注释,时间戳等)提交,那么这条commit命令的意思就非常清晰了,把所有更改的文件加入stage area,并使用上次的提交信息重新提交。 

C) 回滚最近几次commit,并把这几次commit放到叫做topic的branch上去。 
引用
$ git branch topic/wip     (1) 
$ git reset --hard HEAD~3  (2) 
$ git checkout topic/wip   (3)

(1) 你已经提交了一些commit,但是此时发现这些commit还不够成熟,不能进入master分支,但你希望在新的branch上润色这些commit改动。因此执行了git branch命令在当前的HEAD上建立了新的叫做 topic/wip的分支。 
(2) 然后回滚master branch上的最近三次提交。HEAD~3指向当前HEAD-3个commit的commit,git reset --hard HEAD~3即删除最近的三个commit(删除HEAD, HEAD^, HEAD~2),将HEAD指向HEAD~3。 

D) 永久删除最后几个commit 
引用
$ git commit ... 
$ git reset --hard HEAD~3   (1)

(1) 最后三个commit(即HEAD, HEAD^和HEAD~2)提交有问题,你想永久删除这三个commit。 

E) 回滚merge和pull操作 
引用
$ git pull                         (1) 
Auto-merging nitfol 
CONFLICT (content): Merge conflict in nitfol 
Automatic merge failed; fix conflicts and then commit the result. 
$ git reset --hard                 (2) 
$ git pull . topic/branch          (3) 
Updating from 41223... to 13134... 
Fast-forward 
$ git reset --hard ORIG_HEAD       (4)

(1) 从origin拉下来一些更新,但是产生了很多冲突,你暂时没有这么多时间去解决这些冲突,因此你决定稍候有空的时候再重新pull。 
(2) 由于pull操作产生了冲突,因此所有pull下来的改变尚未提交,仍然再stage area中,这种情况下git reset --hard 与 git reset --hard HEAD意思相同,即都是清除index和working tree中被搞乱的东西。 
(3) 将topic/branch合并到当前的branch,这次没有产生冲突,并且合并后的更改自动提交。 
(4) 但是此时你又发现将topic/branch合并过来为时尚早,因此决定退滚merge,执行git reset --hard ORIG_HEAD回滚刚才的pull/merge操作。说明:前面讲过,执行git reset时,git会把reset之前的HEAD放入.git/ORIG_HEAD文件中,命令行中使用ORIG_HEAD引用这个commit。同样的,执行pull和merge操作时,git都会把执行操作前的HEAD放入ORIG_HEAD中,以防回滚操作。 

F) 在被污染的working tree中回滚merge或者pull 
引用
$ git pull                         (1) 
Auto-merging nitfol 
Merge made by recursive. 
nitfol                |   20 +++++---- 
... 
$ git reset --merge ORIG_HEAD      (2)

(1) 即便你已经在本地更改了一些你的working tree,你也可安全的git pull,前提是你知道将要pull的内容不会覆盖你的working tree中的内容。 
(2) git pull完后,你发现这次pull下来的修改不满意,想要回滚到pull之前的状态,从前面的介绍知道,我们可以执行git reset --hard ORIG_HEAD,但是这个命令有个副作用就是清空你的working tree,即丢弃你的本地未add的那些改变。为了避免丢弃working tree中的内容,可以使用git reset --merge ORIG_HEAD,注意其中的--hard 换成了 --merge,这样就可以避免在回滚时清除working tree。 

G) 被中断的工作流程 
在实际开发中经常出现这样的情形:你正在开发一个大的feature,此时来了一个紧急的bug需要修复,但是目前在working tree中的内容还没有成型,还不足以commit,但是你又必须切换的另外的branch去fix bug。请看下面的例子 
引用
$ git checkout feature ;# you were working in "feature" branch and 
$ work work work       ;# got interrupted 
$ git commit -a -m "snapshot WIP"                 (1) 
$ git checkout master 
$ fix fix fix 
$ git commit ;# commit with real log 
$ git checkout feature 
$ git reset --soft HEAD^ ;# go back to WIP state  (2) 
$ git reset                                       (3)

(1) 这次属于临时提交,因此随便添加一个临时注释即可。 
(2) 这次reset删除了WIP commit,并且把working tree设置成提交WIP快照之前的状态。 
(3) 此时,在index中依然遗留着“snapshot WIP”提交时所做的uncommit changes,git reset将会清理index成为尚未提交"snapshot WIP"时的状态便于接下来继续工作。 

(H) Reset单独的一个文件 
假设你已经添加了一个文件进入index,但是而后又不打算把这个文件提交,此时可以使用git reset把这个文件从index中去除。 
引用
$ git reset -- frotz.c                      (1) 
$ git commit -m "Commit files in index"     (2) 
$ git add frotz.c                           (3)

(1) 把文件frotz.c从index中去除, 
(2) 把index中的文件提交 
(3) 再次把frotz.c加入index 

(I) 保留working tree并丢弃一些之前的commit 
假设你正在编辑一些文件,并且已经提交,接着继续工作,但是现在你发现当前在working tree中的内容应该属于另一个branch,与这之前的commit没有什么关系。此时,你可以开启一个新的branch,并且保留着working tree中的内容。 
引用
$ git tag start 
$ git checkout -b branch1 
$ edit 
$ git commit ...                            (1) 
$ edit 
$ git checkout -b branch2                   (2) 
$ git reset --keep start                    (3)

(1) 这次是把在branch1中的改变提交了。 
(2) 此时发现,之前的提交不属于这个branch,此时你新建了branch2,并切换到了branch2上。 
(3) 此时你可以用reset --keep把在start之后的commit清除掉,但是保持working tree不变。 

git revert和git reset的区别

原文:http://blog.csdn.net/koffuxu/article/details/6731876
git revert  是撤销某次操作,此次操作之前的commit都会被保留
git reset  是撤销某次提交,但是此次之后的修改都会被退回到暂存区
具体一个例子,假设有三个commit, git st:
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
当执行 git revert  HEAD~1时, commit2被撤销了
git log可以看到:
commit1:add test1.c
commit3:add test3.c
git status 没有任何变化
如果换做执行 git reset --soft(默认)  HEAD~1后,运行git log
commit2: add test2.c
commit1: add test1.c
运行git status, 则test3.c处于暂存区,准备提交。
如果换做执行 git reset --hard HEAD~1后,
显示:HEAD is now at commit2,运行git log
commit2: add test2.c
commit1: add test1.c
运行git st, 没有任何变化
另外:
git revert <commit log string>是撤消该commit,作为一个新的commit。
Git中从远程的分支获取最新的版本到本地有这样2个命令:
1.  git fetch :相当于是从远程获取最新版本到本地,不会自动merge

    
git fetch origin master
git log -p master..origin/master
git merge origin/master

    以上命令的含义:
   首先从远程的origin的master主分支下载最新的版本到origin/master分支上
   然后比较本地的master分支和origin/master分支的差别
   最后进行合并
   上述过程其实可以用以下更清晰的方式来进行:

git fetch origin master:tmp
git diff tmp 
git merge tmp

    从远程获取最新的版本到本地的test分支上
   之后再进行比较合并
2.  git pull :相当于是从远程获取最新版本并merge到本地

git pull origin master

上述命令其实相当于git fetch 和 git merge
在实际使用中,git fetch更安全一些
因为在merge前,我们可以查看更新情况,然后再决定是否合并
在git中, 我们可以通过 git pull 命令把服务器仓库的更新拉到本地仓库中。 git pull相当于是从远程获取最新版本并merge到本地。

当git clone之后,直接git pull它会自动匹配一个正确的remote url

是因为在config文件中配置了以下内容:

1 [branch "master"]
2 remote = origin
3 merge = refs/heads/master

表明:

1.git处于master这个branch下时,默认的remote就是origin;

2.当在master这个brach下使用指定remote和merge的git pull时,使用默认的remote和merge。

 

但是对于自己建的项目,并用push到远程服务器上,并没有这块内容,需要自己配置。

如果直接运行git pull,会得到如此结果:

 

1 $ git pull
2 Password:
3 You asked me to pull without telling me which branch you
4 want to merge with, and 'branch.master.merge' in
5 your configuration file does not tell me, either. Please
6 specify which branch you want to use on the command line and
7  try again (e.g. 'git pull <repository> <refspec>').
8 See git-pull(1) for details.
9
10 If you often merge with the same branch, you may want to
11 use something like the following in your configuration file:
12
13 [branch "master"]
14 remote = <nickname>
15 merge = <remote-ref>
16
17 [remote "<nickname>"]
18 url = <url>
19 fetch = <refspec>
20
21 See git-config(1) for details.

在参考[2]中,有这样一段:

Note: at this point your repository is not setup to merge _from_ the remote branch when you type 'git pull'. You can either freshly 'clone' the repository (see "Developer checkout" below), or configure your current repository this way:

1 git remote add -f origin login@git.sv.gnu.org:/srv/git/project.git
2 git config branch.master.remote origin
3 git config branch.master.merge refs/heads/master   

 

因此通过git config进行如下配置:

1 $ git config branch.master.remote origin复制代码
2 $ git config branch.master.merge refs/heads/master

或者加上--global选项,对于全部项目都使用该配置。

在git中, 我们可以通过 git push 本地仓库的更新推到服务器仓库。
$ git push ssh://[email protected]/rt4ls.git master // 把本地仓库提交到远程仓库的master分支中
$ git remote add origin ssh://[email protected]/rt4ls.git
$ git push origin master 


这两个操作是等价的,第二个操作的第一行的意思是添加一个标记,让origin指向ssh://[email protected]/rt4ls.git,也就是说你操 作origin的时候,实际上就是在操作ssh://[email protected]/rt4ls.git。origin在这里完全可以理解为后者 的别名。
 需要说明的是,默认情况下这条语句等价于提交本地的master仓库到远程仓库,并作为远程的master分支。
 如果想把本地的某个分支test提交到远程仓库,并作为远程仓库的master分支,或者作为另外一个名叫test的分支,那么可以这么做。


$ git push origin test:master          // 提交本地test分支作为远程的master分支
$ git push origin test:test    
          // 提交本地test分支作为远程的test分支
如果想删除远程的分支呢?类似于上面,如果:左边的分支为空,那么将删除:右边的远程的分支。
$ git push origin :test               // 刚提交到远程的test将被删除,但是本地还会保存的,不用担心
在git中我们可以通过 git rm 命令把一个文件删除,并把它从git的仓库管理系统中移除。但是注意最后要执行 git commit 才真正提交到git仓库
示例1
git rm 1.txt
删除 1.txt文件,并把它从git的仓库管理系统中移除。
示例2
git rm -r myFolder
删除 文件夹 myFolder ,并把它从git的仓库管理系统中移除。
示例3
git add   10.txt
git add -i
           staged     unstaged path
  1:        +0/-0      nothing 10.txt
  2:        +0/-0      nothing branch/t.txt
  3:        +0/-0      nothing branch/t2.txt

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> 7
Bye.
git rm --cached 10.txt
rm '10.txt'
ls
10.txt   2  3.txt  5.txt  readme.txt
git add -i
           staged     unstaged path
  1:        +0/-0      nothing branch/t.txt
  2:        +0/-0      nothing branch/t2.txt
*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now>
在通过  git add   10.txt  命令把文件10,txt添加到索引库中后,又通过  git rm --cached  10.txt  把文件 10.txt 从git的索引库中移除,但是对文件10.txt本身并不进行任何操作。
另外对于已经被 git rm删除掉(还没被提交)的文件或目录,如果想取消其操作的话,可以首先通过 git add -i的子命令 revert从索引库中把它们剔除,然后用 git checkout  <文件>命令来达到取消的目录
关于git add请参考《 git add详解》
关于git checkout请参考《》
在用git来进行版本控制时,我需要执行git commit命令,将索引内容添加到仓库中。
示例1:
git commit   -m  "提交的描述信息"
如果我们这里不用 -m参数的话,git将调到一个文本编译器(通常是vim)来让你输入提交的描述信息
可能一天下来,你对工作树中的许多文档都进行了更新(文档添加、修改、删除),但是我忘记了它们的名字,此时若将所做的全部更新添加到索引中,比较轻省的做法就是:
git commit  -a  -m  "提交的描述信息"
git commit  命令的 -a  选项可只将所有被修改或者已删除的 且已经被git管理 的文档提交倒仓库中如果只是修改或者删除了已被Git 管理的文档,是没必要使用 git add  命令的。
git add  .命令除了能够判断出当前目录(包括其子目录) 所有被修改或者已删除的文档,还能判断 用户所添加的新文档 ,并将其信息追加到索引中。
另外 ,要注意的问题是,Git 不会主动记录你对文档进行的更新,除非你对它发号施令(比如通过git add命令

git diff 可以比较working tree同index之间,index和git directory之间,working tree和git directory之间,git directory中不同commit之间的差异,同时可以通过 [<path>...]参数 将比较限定于特点的 目录或文件  。

git merge的基本用法为把一个分支或或某个commit的修改合并现在的分支上。
我们可以运行git merge -h查看其命令
usage: git merge [options] [<commit>...]
   or: git merge [options] <msg> HEAD <commit>
   or: git merge --abort

    -n                    do not show a diffstat at the end of the merge
    --stat                show a diffstat at the end of the merge
    --summary             (synonym to --stat)
    --log[=<n>]           add (at most <n>) entries from shortlog to merge commi                                                                                                                t message
    --squash              create a single commit instead of doing a merge
    --commit              perform a commit if the merge succeeds (default)
    -e, --edit            edit message before committing
    --ff                  allow fast-forward (default)
    --ff-only             abort if fast-forward is not possible
    --rerere-autoupdate   update the index with reused conflict resolution if po                                                                                                                ssible
    -s, --strategy <strategy>
                          merge strategy to use
    -X, --strategy-option <option=value>
                          option for selected merge strategy
    -m, --message <message>
                          merge commit message (for a non-fast-forward merge)
    -v, --verbose         be more verbose
    -q, --quiet           be more quiet
    --abort               abort the current in-progress merge
    --progress            force progress reporting
    -S, --gpg-sign[=<key id>]
                          GPG sign commit
    --overwrite-ignore    update ignored files (default)
git merge [options] <msg> HEAD <commit> 这里的 HEAD 其实就是分支名,用于说明把 HEAD  分支合并到当前分支。

--squash 选项的含义是:本地文件内容与不使用该选项的合并结果相同,但是不保留待合并分支上的历史信息,也不提交、不移动HEAD,因此需要一条额外的commit命令。其效果相当于将another分支上的多个commit合并成一个,放在当前分支上,原来的commit历史则没有拿过来。
   判断是否使用 --squash 选项最根本的标准是,待合并分支上的历史是否有意义。
如果在开发分支上提交非常随意,甚至写成微博体,那么一定要使用 --squash 选项。版本历史记录的应该是代码的发展,而不是开发者在编码时的活动。
只有在开发分支上每个commit都有其独自存在的意义,并且能够编译通过的情况下(能够通过测试就更完美了),才应该选择缺省的合并方式来保留commit历史。
git clone repo.git

git diff

可以用来比较:

1.staging area和working area的文件 (无其他参数时)

 
  1. git diff  

2.master分支和working area的文件 (用master参数)

 
  1. git diff master   


3.HEAD指向的内容和working area的文件

 
  1. git diff HEAD  


4.用远程master分支比较当前工作区

 
  1. git diff refs/remotes/origin/master  

5.经常还要用到master分支的某个文件的历史版本和working area的该文件的比较

git diff 0c5ee16a6a4c849d0ae0448caa8ff174399c7c3c ./socket_helper.cpp  

上面的命令中, diff后面的参数指的是commit id, ./socket_helper.cpp是要比较的文件路径。


diff的命令输出格式注意:

 
  1. ---代表源文件  
  2. +++代表目标文件  
通常working area的文件都是被当作目标文件来看待。

-开头的行,是只出现在源文件中的行

+开头的行,是只出现在目标文件中的行

空格开头的行,是源文件和目标文件中都出现的行

差异按照差异小结进行组织,每个差异小结的第一行都是定位语句,由@@开头,@@结尾。

 
  1. chenshu@chenshu-yangzhou-home:~/kaimei/data_service/src$ git diff 0c5ee16a6a4c849d0ae0448caa8ff174399c7c3c ./socket_helper.cpp  
  2. diff --git a/data_service/src/socket_helper.cpp b/data_service/src/socket_helper.cpp  
  3. index d606452..047e213 100755  
  4. --- a/data_service/src/socket_helper.cpp  
  5. +++ b/data_service/src/socket_helper.cpp  
  6. @@ -4,6 +4,7 @@  
  7.  #include "data/login_response.h"  
  8.  #include "data/heartbeat_response.h"  
  9.  #include "helper/parser.h"  
  10. +#include "helper/time_measure.h"  
  11.  #include <booster/log.h>  
  12.  #include "exception/socket_error.h"  
  13.  #include "exception/data_error.h"  
上面的diff结果表明

1.某个提交记录0c5ee代表的socket_helper.cpp文件是源文件,当前working area的socket_helper文件是目标文件。

2.在源文件第4行开始的6行和目标文件第4行开始的7行构成一个差异小结

3.这个差异小结中,目标文件添加了一行#include "helper/time_measure.h"

4.其他空格开头的行表明没有差异。

 

 

  1. 给源码树加 patch

进入源码树的根目录下:

cd SRC_DIR
patch -p 1 < /path/to/your/patch

-p 1 指定忽略的目录个数,如你的patch头为 diff -urN orig/include/linux/module.h tgt/include/linux/module.h,则是对 $SRC_DIR/ 下的 include/linux/modue.h 应用该patch

-p 2 则是对$SRC_DIR/ 下的 linux/modue.h 应用该 patch


2. 移去加入的 patch

cd SRC_DIR
patch -R -p1 </path/to/your/patch


3. 模拟打补丁

有时我们需要测试一下,自己生成patch 能否正确的应用到目标源码树下而没有冲突,则:

patch --dry-run -p1 < /path/to/your/patch


4. 常见错误

patch: **** malformed patch at line 129

出现这中错误,一般是 patch 生成后被手工修改了,如下的patch:

diff -urN a/include/asm-mips/module.h b/include/asm-mips/module.h
--- a/include/asm-mips/module.h   1970-01-01 00:00:00.000000000 +0000
+++ b/include/asm-mips/module.h    2008-01-03 16:51:23.000000000 +0000
@@ -104,6 +104,8 @@
#define MODULE_PROC_FAMILY "NEVADA "
#elif defined CONFIG_CPU_R8000
#define MODULE_PROC_FAMILY "R8000 "
+#elif defined CONFIG_CPU_R9721
+#define MODULE_PROC_FAMILY "R9721"
#elif defined CONFIG_CPU_R10000
#define MODULE_PROC_FAMILY "R10000 "
#elif defined CONFIG_CPU_RM7000


数字6,表示记录了6行原始文件,数字8表示记录了8行目标文件

如果你这时手工加了一行:

@@ -104,6 +104,8 @@
#define MODULE_PROC_FAMILY "NEVADA "
#elif defined CONFIG_CPU_R8000
#define MODULE_PROC_FAMILY "R8000 "
+#elif defined CONFIG_CPU_R9721
+#define MODULE_PROC_FAMILY "R9721"
+#define MODULE_PROC_ABC "ABC"
#elif defined CONFIG_CPU_R10000
#define MODULE_PROC_FAMILY "R10000 "
#elif defined CONFIG_CPU_RM7000

这是你应用这个补丁,patch 就会提示失败,并输出:

patch: **** malformed patch at line xxx

应用时,patch 都会检查受影响的行是否与记录在两个 @@ 之间的数值一致,手工加一行后,记录的目标文件行数为9,因此patch会失败。

将@@ -104,6 +104,8 @@ 改为@@ -104,6 +104,9 @@ 即可成功打上patch
=============
git log --oneline -5  -- xx.c
git show fdddeee  -- xx.c
git show fdddeee --raw
 
===========
ctr+r   
git log --oneline  remots_branch

 

你可能感兴趣的:(Git)