Git rebase 详解

1.出现情况的背景:

当你提交的代码后,管理员发现,您的代码不能提交到服务器上,主要原因在于,你的commit 中和服务器中的有些commit不再同一时间轴上,即:你的有些commit要插入到服务器中的某些commit之间,这样就会造成代码的冲突。所以这个时候就要使用git rebase。

假如,你平时使用的分支叫new ,然后在这个分支上你刚提交过几个commit。

做法:

1.新建一个分支,并且代码和服务器中代码同步

[codesyntax lang=”text”]


git checkout origin/v2.0 -b temp

[/codesyntax]

2.为了保证新建的temp分支代码是最新的,可以多执行下面一步

[codesyntax lang=”text”]


git pull

[/codesyntax]

3.当你新建分支后,系统会自动checkout到temp分支上,此时

[codesyntax lang=”text”]


git checkout new

[/codesyntax]

4.合并代码,并整理

[codesyntax lang=”text”]


git rebase temp //会将temp分支的代码合并过来,并按照提交的顺序排序

[/codesyntax]

5. 因为顺序是重新整理的,所以肯定会出现冲突

6.解决冲突,最后git add * ,但不许要git commit

7.解决后,执行

[codesyntax lang=”text”]


git rebase --continue

[/codesyntax]

8.重新提交代码

[codesyntax lang=”text”]


git push for-*

[/codesyntax]

注意:如果要对某些代码的commit重新整理

1. 可以记住某个commit号

2. git rebase -i commit号

3. 会显示一个整理提交的界面,有很多参数,e。p。等等

4.将前面的参数改为e。则wq保存后,系统会自动让你重新修改commit内容

5.修改完成后,再git push for-*

Git 乱码处理方法

乱码情景1

在cygwin中,使用git add添加要提交的文件的时候,如果文件名是中文,会显示形如274\232\350\256\256\346\200\273\347\273\223.png的乱码。

解决方案:

在bash提示符下输入:

[codesyntax lang=”text”]

git config --global core.quotepath false

[/codesyntax]
core.quotepath设为false的话,就不会对0×80以上的字符进行quote。中文显示正常。

乱码情景2

在MsysGit中,使用git log显示提交的中文log乱码。

解决方案:

设置git gui的界面编码

[codesyntax lang=”text”]

git config --global gui.encoding utf-8

[/codesyntax]
设置 commit log 提交时使用 utf-8 编码,可避免服务器上乱码,同时与linux上的提交保持一致!

[codesyntax lang=”text”]

git config --global i18n.commitencoding utf-8

[/codesyntax]
使得在 $ git log 时将 utf-8 编码转换成 gbk 编码,解决Msys bash中git log 乱码。

[codesyntax lang=”text”]

git config --global i18n.logoutputencoding gbk

[/codesyntax]
使得 git log 可以正常显示中文(配合i18n.logoutputencoding = gbk),在 /etc/profile 中添加:

[codesyntax lang=”text”]

export LESSCHARSET=utf-8

[/codesyntax]

乱码情景3

在MsysGit自带的bash中,使用ls命令查看中文文件名乱码。cygwin没有这个问题。

解决方案:

使用?lls --show-control-chars?命令来强制使用控制台字符编码显示文件名,即可查看中文文件名。

为了方便使用,可以编辑?/etc/git-completion.bash?,新增一行?alias ls="ls --show-control-chars"

Git ignore详解

环境

Windows XP SP3 + TortoiseGit + msysGit

 

ignore files的三种方法

以下涉及的ignore文件均为如下格式:

#?以’#’开始的行,被视为注释.#?忽略掉所有文件名是?foo.txt的文件.

foo.txt

#?忽略所有生成的?html文件,

*.html

# foo.html是手工维护的,所以例外.

!foo.html

#?忽略所有.o和?.a文件.

*.[oa]

 

【方式一】

在仓库目录下新建一个名为.gitignore的文件(因为是点开头,没有文件名,没办法直接在windows目录下直接创建,必须通过右键Git Bash,按照linux的方式来新建.gitignore文件)。如下图所示。

.gitignore文件对其所在的目录及所在目录的全部子目录均有效。通过将.gitignore文件添加到仓库,其他开发者更新该文件到本地仓库,以共享同一套忽略规则。

【方式二】

通过配置.git/info/exclude文件来忽略文件。这种方式对仓库全局有效,只能对自己本地仓库有作用,其他人没办法通过这种方式来共享忽略规则,除非他人也修改其本地仓库的该文件。

 

【方式三】

通过.git/config配置文件的core. Excludesfile选项,指定一个忽略规则文件(完整路径),如下图所示。忽略规则在文件e:/gitignore.txt中(当然该文件名可以任意取)。

该方式的作用域是也全局的。

 

【例子】

[codesyntax lang=”text”]
# 忽略*.o和*.a文件
?*.[oa]
# 忽略*.b和*.B文件,my.b除外
*.[bB]
!my.b
# 忽略dbg文件和dbg目录
dbg
# 只忽略dbg目录,不忽略dbg文件
dbg/
# 只忽略dbg文件,不忽略dbg目录
dbg
!dbg/
# 只忽略当前目录下的dbg文件和目录,子目录的dbg不在忽略范围内
/dbg
[/codesyntax]

解决Git pull出现non-fast-forward错误

当要push代码到git时,出现提示:

error:failed to push some refs to …

Dealing with “non-fast-forward” errors
From time to time you may encounter this error while pushing:

$ git push origin master
To ../remote/
! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to ‘../remote/’

To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the ‘non-fast forward’
section of ‘git push –help’ for details.
This error can be a bit overwhelming at first, do not fear. Simply put, git cannot make the change on the remote without losing commits, so it refuses the push. Usually this is caused by another user pushing to the same branch. You can remedy this by fetching and merging the remote branch, or using pull to perform both at once.
In other cases this error is a result of destructive changes made locally by using commands like git commit –amend or git rebase. While you can override the remote by adding –force to the push command, you should only do so if you are absolutely certain this is what you want to do. Force-pushes can cause issues for other users that have fetched the remote branch, and is considered bad practice. When in doubt, don’t force-push.

 

问题(Non-fast-forward)的出现原因在于:git仓库中已经有一部分代码,所以它不允许你直接把你的代码覆盖上去。于是你有2个选择方式:

1,强推,即利用强覆盖方式用你本地的代码替代git仓库内的内容

git push -f

2,先把git的东西fetch到你本地然后merge后再push

$ git fetch

$ git merge

这2句命令等价于

  1. $ git pull

可是,这时候又出现了如下的问题:

上面出现的 [branch “master”]是需要明确(.git/config)如下的内容
[branch “master”]
remote = origin

merge = refs/heads/master

这等于告诉git2件事:

1,当你处于master branch, 默认的remote就是origin。

2,当你在master branch上使用git pull时,没有指定remote和branch,那么git就会采用默认的remote(也就是origin)来merge在master branch上所有的改变

如果不想或者不会编辑config文件的话,可以在bush上输入如下命令行:

$ git config branch.master.remote origin
$ git config branch.master.merge refs/heads/master

之后再重新git pull下。最后git push你的代码吧。it works now~

Git branch详解

查看分支:
$ git branch    该命令会类出当先项目中的所有分支信息,其中以*开头的表示当前所在的分支。参数-r列出远程仓库中的分支,而-a则远程与本地仓库的全部分支。
创建新分支:
$ git branch testing    创建一个名为testing的分支

切换分支:
$ git checkout teting   切换到testing分支上。通过向该命令传递一个-b参数,可以实现创建并切换分支的功能。

合并分支:
$ git merge hotfix      将hotfix分支合并到当前分支当中去

删除分支:
$ git branch -d hotfix  删除分支hotfix,-d选项只能删除已经被当前分支所合并过的分支,而要强制删除没有被合并过的分支,可以使用-D。

重命名分支:
$ git branch -m oldbranch newbranch     -M用来强制重命名,如newbranch已经存在的时候。

查看分支之间的不同:
$ git diff branchName   查看当前分支与branchName分支之间的差异,也可以使用:$ git diff branch1 branch2 来比较这1和2分支之间的差异,当使用第一种方式比较时,如果当前工作目录中存在与branchName同名的文件,系统则会提示错误,要是指明要比较的是文件还是分支,如果比较分支,可以进入.git中进行比较或切换分支,如果是>比较文件,则使用$ git diff — fileName命令。
$ git diff <branchA>:<fileA> <branchB>:<fileB>
$ git ls-tree -r branch 列出所有的树对象

合并冲突:
如果在不同的分支中都修改了同一个文件的同一部分,Git 就无法干净地把两者合到一起(译注:逻辑上说,这种问题只能由人来裁决。)
任何包含未解决冲突的文件都会以未合并(unmerged)的状态列出。Git 会在有冲突的文件里加入标准的冲突解决标记,可以通过它们来手工定位并解决这些冲突。
在解决了所有文件里的所有冲突后,运行 git add 将把它们标记为已解决状态(译注:实际上就是来一次快照保存到暂存区域。)。因为一旦暂存,就表示冲突已经解决。如
果你想用一个有图形界面的工具来解决这些问题,不妨运行 git mergetool,它会调用一个可视化的合并工具并引导你解决所有冲突。
要从该清单中筛选出你已经(或尚未)与当前分支合并的分支,可以用 –merge 和 –no-merged 选项(Git 1.5.6 以上版本)。比如用 git branch –merge 查看哪些分支>已被并入当前分支(译注:也就是说哪些分支是当前分支的直接上游。)

远程分支:
远程分支是对远程仓库分支的索引。它们是一些无法移动的本地分支,只有在Git进行网络交互时才会更新。我们用(远程仓库名)/(分支名)来表示远程分支。比如想查看上次>同origin仓库通讯时master的样子,就应该查看origin/master分支。

推送本地分支:
$ git push (远程仓库名字) (分支名)  如:$ git push orgin serverfix 该命令会将本地serverfix分支推送到origin远程仓库的serverfix分支中去,也可以使用命令 $ git push origin serverfix:serferfix实现同样的效果,可以将第二个serverfix更改为其它名字来指定要将该本地分支推送到远程仓库中的的指定分支中去,如果不存在,则会在
远程仓库中新建分支。

获取远程分支:
在使用git clone命令从远程服务器克隆Git仓库时,只是将远程仓库当前分支的内容克隆到本地,要是克隆其他分支的内容,需要使用下面命令:可通过git branch -r命令来
查看想要获取的远程仓库中的分支。
$ git fetch origin  值得注意的是,在 fetch 操作下载好新的远程分支之后,你仍然无法在本地编辑该远程仓库中的分支。
如果要把该内容合并到当前分支,可以运行 git merge origin/serverfix。如果想要一份自己的 serverfix 来开发,可以在远程分支的基础上分化出一个新的分支来:
$ git checkout -b serverfix origin/serverfix
这会切换到新建的 serverfix 本地分支,其内容同远程分支 origin/serverfix 一致,这样你就可以在里面继续开发了。

Git pull:
从服务器的仓库中获取代码,和本地代码合并。(与服务器交互,从服务器上下载最新代码,等同于: Git fetch + Git merge)。
从其它的版本库(既可以是远程的也可以是本地的)将代码更新到本地,例如:“git pull origin master ”就是将origin这个版本库的代码更新到本地的master主分支。
git pull可以从任意一个git库获取某个分支的内容。用法如下:
git pull username@ipaddr: 远端repository名 远端分支名:本地分支名。这条命令将从远端git库的远端分支名获取到本地git库的一个本地分支中。其中,如果不写本地
分支名,则默认pull到本地当前分支。
需要注意的是,git pull也可以用来合并分支。 和git merge的作用相同。 因此,如果你的本地分支已经有内容,则git pull会合并这些文件,如果有冲突会报警。

Git push
将本地commit的代码更新到远程版本库中,例如 “git push origin”就会将本地的代码更新到名为orgin的远程版本库中。
git push和git pull正好想反,是将本地某个分支的内容提交到远端某个分支上。用法: git pushusername@ipaddr: 远端repository名 本地分支名:远端分支名。这条命
令将本地git库的一个本地分支push到远端git库的远端分支名中。
需要格外注意的是,git push好像不会自动合并文件。因此,如果git push时,发生了冲突,就会被后push的文件内容强行覆盖,而且没有什么提示。 这在合作开发时是>很危险的事情。

git-clone命令只要碰到类似下面格式的远程仓库地址,都会被认为地址是符合SSH协议的:        账户@IP:工作目录

git checkout -b [分支名] [远程名]/[分支名]
如果你有 1.6.2 以上版本的 Git,还可以用 –track 选项简化
$ git checkout –track origin/serverfix

删除远程分支:
git push [远程名] :[分支名]

git pull 远程仓库名 远程分支:本地分支
git push 远程仓库名 远程分支:本地分支
git checkout -b 分支名 远程仓库名/分支名

Git Merge详解

git merge 用来做分支合并,将其他分支中的内容合并到当前分支中。比如分支结构如下:
[codesyntax lang=”text”]

                        master
                         /
C0 ---- C1 ---- C2 ---- C4
                         \
                         C3 ---- C5
                                  \
                                issueFix

[/codesyntax]
当前分支是master
$ git checkout master

把issueFix中的内容Merge进来:
$ git merge issueFix

如果没有冲突的话,merge完成。有冲突的话,git会提示那个文件中有冲突,比如有如下冲突:

<<<<<<< HEAD:test.c

printf (“test1″);

=======

printf (“test2″);

>>>>>>> issueFix:test.c

可以看到 ======= 隔开的上半部分,是 HEAD(即 master 分支,在运行 merge 命令时检出的分支)中的内容,下半部分是在 issueFix 分支中的内容。解决冲突的办法无非是二者选其一或者由你亲自整合到一起。比如你可以通过把这段内容替换为下面这样来解决:

printf (“test2″);

这个解决方案各采纳了两个分支中的一部分内容,而且删除了 <<<<<<<,=======,和>>>>>>> 这些行。在解决了所有文件里的所有冲突后,运行 git add 将把它们标记为已解决(resolved)。因为一旦暂存,就表示冲突已经解决。如果你想用一个有图形界面的工具来解决这些问题,不妨运行 git mergetool,它会调用一个可视化的合并工具并引导你解决所有冲突:

$ git mergetool
merge tool candidates: kdiff3 tkdiff xxdiff meld gvimdiff opendiff emerge vimdiff
Merging the files: index.html

Normal merge conflict for ‘test.c’:
{local}: modified
{remote}: modified
Hit return to start merge resolution tool (kdiff3):

合并后的分支图如下:
[codesyntax lang=”text”]

                               master
                                 /
C0 ---- C1 ---- C2 ---- C4 ---- C6
                        \       /
                        C3 ----C5
                                \
                              issueFix

[/codesyntax]
注意,这次合并的实现,由于当前 master 分支所指向的 commit (C4)并非想要并入分支(issueFix)的直接祖先,Git 不得不进行一些处理。就此例而言,Git 会用两个分支的末端(C4 和 C5)和它们的共同祖先(C2)进行一次简单的三方合并。对三方合并的结果作一新的快照,并自动创建一个指向它的 commit(C6)

退出合并工具以后,Git 会询问你合并是否成功。如果回答是,它会为你把相关文件暂存起来,以表明状态为已解决。然后可以用 git commit 来完成这次合并提交。

Git 常用操作详解

简介

版本控制系统(VCS, Version Control System) 可以分为集中式(CVCS, Centralized Version Control System, 如 CVS, Subversion)和分布式(DVCS, Distributed Version Control System,如 Git 等)版本控制系统。

传统的集中式版本控制系统,本地只保存代码库的一个版本拷贝。 所有历史版本都保存在服务器。GIT 与之最大的不同是,本地不仅保存一个快照,而且保存着整个代码库(repository)。因此它可以“离线”工作。

在 Window 上安装: http://code.google.com/p/msysgit

GIT 起源于 LINUX 开发。Linux 开发早期(1992-2002)没有使用版本控制工具,直到 2002 年开始使用一个非开源的工具 BitKeeper。一开始这个工具还给 Linux 免费使用,后来想收费了,充满自由精神 Linux 成员们肯定不会屈服于这个要挟,一怒之下开发了一个自由的版本控制工具。2005 年,GIT 诞生 。

参考: 官网:http://git-scm.com/

手册:http://www.kernel.org/pub/software/scm/git/docs/

参考:http://gitref.org/

ProGit: http://progit.org/book/

GIT 基础

GIT 使用 SHA-1 哈希码(40个字符)来标识提交,同时保证本次提交后整体(一个快照)的完整性。

文件状态:

文件状态分为:未跟踪 (untracked) 和已跟踪 (tracked),已跟踪又分为三种状态: 已暂存(staged),已修改(modified),已提交(committed)

一般过程如下:

1) 新建文件,该文件状态为“未跟踪”,位于工作区

2) 用 git add a.txt? 加入该文件,状态变为已跟踪的“已暂存”,位于暂存区

3) 用 git commit a.txt -m “ha”? 提交该文件,状态变为“已提交”,位于代码库(repository )

或者,如果存在修改的情况,增加如下2.1和2.2两个步骤:

1) 新建文件,该文件状态为“未跟踪”,位于工作区

2) 用 git add a.txt? 加入该文件,状态变为已跟踪的“已暂存”,位于暂存区

2.1)编辑该文件并保存,状态变为“已修改”,位于工作区。(注意,位于暂存区的文件独立存在!)

2.2) 用 git add a.txt? 加入该文件,状态变为“已暂存”,位于暂存区。(注意,原暂存区的文件被覆盖!)

3) 用 git commit a.txt -m “ha”? 提交该文件,状态变为“已提交”,位于代码库(repository )

考虑更广泛的情况,状态迁移图如下所示:

Git?<wbr>使用?<wbr>-?<wbr>1.?<wbr>文件操作和历史查看

注意:用 git status 查看目前所有文件的状态。

GIT 配置:

三种配置范围类型:

1)所有用户 –system,?? 存在 /etc/gitconfig 文件中。(对windows来说,是 msysgit 的安装目录)

2)本用户 –global,?? 存在 ~/.gitconfig? 文件中。(对windows 来说,是 C:\Documents and Settings\$USER)

3)本项目?? 存在 .git/config 文件中。

注意:后面的重载前面的。例如:用–global设置,可以在所有项目中使用这个设置;如果有一个项目你想使用一个特别的设置,就可以使用不带参数的 git config 重新设置,则它只作用于这个项目。如果用 git config –list 查看这些设置,可能会列出多个,但最后那个起作用。

用户信息

$ git config –global user.name “iprayz”
$ git config –global user.email iprayz@example.com

文本编辑器

$ git config –global core.editor emacs

查看配置信息

$ git config –list

或者只看一个信息:

$ git config <key>

 

常用操作

(GIT 1.7.4 on? Windows)

获取帮助:?? $ git help <verb>

初始化仓库:? $ git init

(说明: 如果该目录有文件,则都会处于“未跟踪”状态的。)

克隆仓库:? $ git clone git://github.com/schacon/grit.git

克隆仓库,并换个名字:?? $ git clone git://github.com/schacon/grit.git mygrit

跟踪一个新文件:? $ git add readme.txt

说明:

1) 跟踪之后,该文件状态是“已暂存”的。 (Changes to be committed:)

2)修改一个已暂存的文件,该文件会出现在两个记录区中。

3) 如果跟踪错了,想把他删除(不删除工作区的),则用 git rm –cached readme.txt。状态变成“未跟踪”,如果该文件已经修改了,则加? -f 参数强行删除暂存区的文件(已修改的文件不被覆盖)。

跟踪一组新文件:? $ git add *.txt

跟踪一个目录中的所有文件:? $ git add mydir

说明:如果该目录下有子目录,则进行递归操作。

修改之后,暂存一个文件:?? $ git add readme.txt

说明:取消已暂存的文件(已暂存到已修改):? $ git reset HEAD readme.txt

忽略某些文件:? 在.gitignore 文件中加入下面两行:? *.[oa]? *~

*.a? # 忽略所有 .a 结尾的文件
!lib.a? # 但 lib.a 除外
/TODO? # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/? # 忽略 build/ 目录下的所有文件
doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt

注意:

.gitignore 文件放在工程的根目录即可,但是要把它用 git add 加入跟踪或者提交。

比较:

查看尚未暂存的更新:? $ git diff

说明:比较“已修改”和“已暂存(或已提交)”。

查看尚未提交的更新:? $ git diff –cached

或? $ git diff –staged

说明:比较“已暂存”和已提交。

提交:

提交更新(只更新暂存中的):? $ git commit

提交更新(只更新暂存中的):? $ git commit -m “task12, added implementation for usr mrg.”

直接提交更新(更新暂存中的和已修改的): $ git commit -a -m “task12, added implementation forg.”

从文件中取注释:?? $ git commit –file notefile

重新获取:

抛弃已修改,用已提交覆盖?? $ git checkout A.java

说明:此命令对已暂存文件没作用。

删除文件:

从工作区可以直接删除文件,这是运行 git status, 显示:

Changes not staged for commit:

(use “git add/rm <file>…” to update what will be committed)

(use “git checkout — <file>…” to discard changes in working directory)

deleted:?? a

可以用 git rm 删除 a。注意:如果 a 是已提交的文件,则还需要运行 git commit 以确保在代码库中删除。如果该文件尚未提交,则无需运行git commit。

也可以直接使用 git rm 删除文件,但如何文件处于“已修改” 则需要加 -f

移除已跟踪文件,恢复到“未跟踪”?? $ git rm –cached A.java

说明:如果文件已修改,则需 -f ,并且不覆盖修改过的内容。

强行移除修改后文件(从暂存区和工作区中删除):? $ git rm -f a.a

移除目录下的所有文件(递归):? $ git rm log/\*.log

移除目录下的所有文件(无递归):? $ git rm log/*.log

改名(只改工作区和暂存区):? $ git mv file1 file2

相当于:? $ mv README.txt README
$ git rm README.txt
$ git add README

历史查看 :

查看提交历史(全部):? $ git log

查看提交历史,并显示统计信息:? $ git log –stat

查看提交历史并查看差异:? $ git log -p

查看最近2次提交历史并查看差异:? $ git log -p -2

查看最近2周内提交历史:? $ git log –since=2.weeks

查看某个时刻之后的提交历史:? $ git log –since=”2008-09-14″

查看某个时刻以前的提交历史:? $ git log –until=”2008-09-14″

查看某个作者的提交历史:? $ git log –author=”stupid”

其他:

-(n) 仅显示最近的 n 条提交
–since, –after 仅显示指定时间之后的提交。
–until, –before 仅显示指定时间之前的提交。
–author 仅显示指定作者相关的提交。
–committer 仅显示指定提交者相关的提交。

例如:

$ git log –pretty=”%h:%s” –author=gitster –since=”2008-10-01″ \
–before=”2008-11-01″ –no-merges — t/

查看提交历史,并单行显示:? $ git log –pretty=oneline

查看提交历史,并格式化显示:? $ git log –pretty=format:”%h – %an, %ar : %s”

例如:

$ git log –pretty=format:”%h – %an, %ar : %s”
[codesyntax lang=”text”]

ca82a6d - Scott Chacon, 11 months ago : changed the version number
085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code
a11bef0 - Scott Chacon, 11 months ago : first commit

[/codesyntax]

%H 提交对象(commit)的完整哈希字串
%h 提交对象的简短哈希字串
%T 树对象(tree)的完整哈希字串
%t 树对象的简短哈希字串
%P 父对象(parent)的完整哈希字串
%p 父对象的简短哈希字串
%an 作者(author)的名字
? 作者的电子邮件地址
? 作者修订日期(可以用 -date= 选项定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者(committer)的名字
? 提交者的电子邮件地址
? 提交日期
%cr 提交日期,按多久以前的方式显示
%s 提交说明

查看提交历史,并图形化显示:? $ git log –pretty=format:”%h %s” –graph

例如:

$ git log –pretty=format:”%h %s” –graph

[codesyntax lang=”text”]

* 2d3acf9 ignore errors from SIGCHLD on trap
*? 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
*? 11d191e Merge branch 'defunkt' into local

[/codesyntax]

其它:

-p 按补丁格式显示每个更新之间的差异。
–stat 显示每次更新的文件修改统计信息。
–shortstat 只显示 –stat 中最后的行数修改添加移除统计。
–name-only 仅在提交信息后显示已修改的文件清单。
–name-status 显示新增、修改、删除的文件清单。
–abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
–relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。
–graph 显示 ASCII 图形表示的分支合并历史。
–pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。

最重要的是,如果你觉着上面这些查看历史的命令太难用,你可以使用图形化工具:gitk,一切都清晰了。

Git log参数详解

git log 查看提交记录,参数:
-n      (n是一个正整数),查看最近n次的提交信息
[codesyntax lang=”text”]

$ git log -2    
查看最近2次的提交历史记录

[/codesyntax]

— fileName     fileName为任意文件名,查看指定文件的提交信息。(注:文件名应该放到参数的最后位置,通常在前面加上–并用空格隔开表示是文件。)
[codesyntax lang=”text”]

$ git log file1 file2   查看file1文件file2文件的提交记录
$ git log file/         查看file文件夹下所有文件的提交记录

[/codesyntax]

–branchName    branchName为任意一个分支名字,查看莫个分支上的提交记录。同上,需要放到参数中的最后位置处。(注:如果分支名与文件名相同,系统会提示错误,可通过–选项来指定给定的参数是分支名还是文件名。)例:在当前分支中有一个名为v1的文件,同时还存在一个名为v1的分支,则:
[codesyntax lang=”text”]

$ git log v1 
-- 此时的v1代表的是分支名字
$ git log -- v1 此时的v1代表的是名为v1的文件
$ git log v1 -- v1

[/codesyntax]

tagName或branchame               查询指定标签/分支中的提交记录信息
[codesyntax lang=”text”]

$ git log v1.0..        查询从v1.0以后的提交历史记录(不包含v1.0)
$ git log test..master  查询master分支中的提交记录但不包含test分支记录
$ git log master..test  查询test分支中的提交记录但不办含master分支记录
$ git log master...test 查询master或test分支中的提交记录。
$ git log test --not master  屏蔽master分支

[/codesyntax]

根据commit查询日志
[codesyntax lang=”text”]

$ git log commit    查询commit之前的记录,包含commit
$ git log commit1 commit2 查询commit1与commit2之间的记录,包括commit1和commit2
$ git log commit1..commit2 同上,但是不包括commit1

[/codesyntax]

其中,commit可以是提交哈希值的简写模式,也可以使用HEAD代替。HEAD代表最后一次提交,HEAD^为最后一个提交的父提交,等同于HEAD~1,HEAD~2代表倒数第二次提交
–pretty
       按指定格式显示日志信息,可选项有:oneline,short,medium,full,fuller,email,raw以及format:<string>,默认为medium,可以通过修改配置文件来指定默认的
方式。
[codesyntax lang=”text”]

$ git log (--pretty=)oneline

[/codesyntax]

常见的format选项:

[codesyntax lang=”text”]

选项     说明
%H      提交对象(commit)的完整哈希字串
%h      提交对象的简短哈希字串
%T      树对象(tree)的完整哈希字串
%t      树对象的简短哈希字串
%P      父对象(parent)的完整哈希字串
%p      父对象的简短哈希字串
%an     作者(author)的名字
%ae     作者的电子邮件地址
%ad     作者修订日期(可以用 -date= 选项定制格式)
%ar     作者修订日期,按多久以前的方式显示
%cn     提交者(committer)的名字
%ce     提交者的电子邮件地址
%cd     提交日期
%cr     提交日期,按多久以前的方式显示
%s      提交说明

[/codesyntax]

注:作者是指最后一次修改文件的人;而提交者是指提交该文件的人。
[codesyntax lang=”text”]

$ git log --pretty=format:"%an %ae %ad %cn %ce %cd %cr %s" --graph

[/codesyntax]

–mergs 查看所有合并过的提交历史记录
–no-merges     查看所有未被合并过的提交信息
–author=someonet       查询指定作者的提交记录
[codesyntax lang=”text”]

$ git log --author=gbyukg

[/codesyntax]

–since,–affter       仅显示指定时间之后的提交(不包含当前日期)
–until,–before       仅显示指定时间之前的提交(包含当前日期)
[codesyntax lang=”text”]

$ git log --before={3,weeks,ago} --after={2010-04-18}

[/codesyntax]

–grep  通过提交说明信息过滤提交日志
[codesyntax lang=”text”]

$ git log --grep=hotfix 该命令会列出所有包含hotfix字样的提交信息说明的提交记录

[/codesyntax]

注意:如果想同时使用–grep和–author,必须在附加一个–all-match参数。
-S      通过查询文件的变更内容来检索出指定提交日志 注:-S后没有”=”,与查询内容之间也没有空格符
[codesyntax lang=”text”]

$ git log --Snew

[/codesyntax]

-p      查看提交时的补丁信息
[codesyntax lang=”text”]

$ git log -p --no-merges -2

[/codesyntax]

–stat  列出文件的修改行数
–sortstat      只显示–stat中最后行数修改添加移除的统计
–graph 以简单的图形方式列出提交记录
–abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。
–relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。
–name-only 仅在提交信息后显示已修改的文件清单。
–name-status 显示新增、修改、删除的文件清单。

GIT Blame
用来查看文件的每个部分修改详情
[codesyntax lang=”text”]

$git blame index.php

[/codesyntax]

Git push错误及解决方法

在使用Git Push代码到数据仓库时,提示如下错误: [codesyntax lang=”text”]

[remote rejected] master -> master (branch is currently checked out)
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To git@192.168.1.X:/var/git.server/.../web
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push Test refs to 'git@192.168.1.X:/var/git.server/.../web'

[/codesyntax]

这是由于git默认拒绝了push操作,需要进行设置,修改.git/config添加如下代码:

[codesyntax lang=”text”]

[receive]
    denyCurrentBranch = ignore

[/codesyntax]

注意上面修改的是代码仓库的config,而不是本地分支的config

在初始化远程仓库时最好使用 git –bare init   而不要使用:git init

如果使用了git init初始化,则远程仓库的目录下,也包含work tree,当本地仓库向远程仓库push时,   如果远程仓库正在push的分支上(如果当时不在push的分支,就没有问题), 那么push后的结果不会反应在work tree上,  也即在远程仓库的目录下对应的文件还是之前的内容,必须得使用git reset –hard才能看到push后的内容.

Github常见问题

如果输入$ git remote add origin git@github.com:iprayz(github帐号名)/test(项目名).git

提示出错信息:fatal: remote origin already exists.

解决办法如下:

1、先输入$ git remote rm origin

2、再输入$ git remote add origin git@github.com:iprayz/test.git 就不会报错了!

3、如果输入$ git remote rm origin 还是报错的话,error: Could not remove config section ‘remote.origin’. 我们需要修改gitconfig文件的内容

4、找到你的github的安装路径,我的是C:\Users\ASUS\AppData\Local\GitHub\PortableGit_ca477551eeb4aea0e4ae9fcd3358bd96720bb5c8\etc

5、找到一个名为gitconfig的文件,打开它把里面的[remote "origin"]那一行删掉就好了!

如果输入$ ssh -T git@github.com

出现错误提示:Permission denied (publickey)

因为新生成的key不能加入ssh就会导致连接不上github。

解决办法如下:

1、先输入$ ssh-agent,再输入$ ssh-add ~/.ssh/id_key,这样就可以了。

2、如果还是不行的话,输入ssh-add ~/.ssh/id_key 命令后出现报错Could not open a connection to your authentication agent.解决方法是key用Git Gui的ssh工具生成,这样生成的时候key就直接保存在ssh中了,不需要再ssh-add命令加入了,其它的user,token等配置都用命令行来做。

3、最好检查一下在你复制id_rsa.pub文件的内容时有没有产生多余的空格或空行,有些编辑器会帮你添加这些的。

如果输入$ git push origin master

提示出错信息:error:failed to push som refs to …….

解决办法如下:

1、先输入$ git pull origin master //先把远程服务器github上面的文件拉下来

2、再输入$ git push origin master

3、如果出现报错 fatal: Couldn’t find remote ref master或者fatal: ‘origin’ does not appear to be a git repository以及fatal: Could not read from remote repository.

4、则需要重新输入$ git remote add origin git@github.com:iprayz/test.git

使用git在本地创建一个项目的过程

[codesyntax lang=”bash”]

$ makdir ~/hello-world??? //创建一个项目hello-world
$ cd ~/hello-world?????? //打开这个项目
$ git init???????????? //初始化
$ touch README
$ git add README??????? //更新README文件
$ git commit -m 'first commit'???? //提交更新,并注释信息“first commit”
$ git remote add origin git@github.com:defnngj/hello-world.git???? //连接远程github项目
$ git push -u origin master???? //将本地项目更新到github项目上去

[/codesyntax]

gitconfig配置文件

Git有一个工具被称为git config,它允许你获得和设置配置变量;这些变量可以控制Git的外观和操作的各个方面。这些变量可以被存储在三个不同的位置:

1./etc/gitconfig 文件:包含了适用于系统所有用户和所有库的值。如果你传递参数选项’–system’ 给 git config,它将明确的读和写这个文件。
2.~/.gitconfig 文件 :具体到你的用户。你可以通过传递–global 选项使Git 读或写这个特定的文件。
3.位于git目录的config文件 (也就是 .git/config) :无论你当前在用的库是什么,特定指向该单一的库。每个级别重写前一个级别的值。因此,在.git/config中的值覆盖了在/etc/gitconfig中的同一个值。

PS: 在Windows系统中,Git在$HOME目录中查找.gitconfig文件(对大多数人来说,位于C:\Documents and Settings\$USER下)。它也会查找/etc/gitconfig,尽管它是相对于Msys 根目录的。这可能是你在Windows中运行安装程序时决定安装Git的任何地方。

配置相关信息:

2.1 当你安装Git后首先要做的事情是设置你的用户名称和e-mail地址。这是非常重要的,因为每次Git提交都会使用该信息。它被永远的嵌入到了你的提交中:

$ git config –global user.name “John Doe”

$ git config –global user.email johndoe@example.com

2.2??? 你的编辑器(Your Editor)

现在,你的标识已经设置,你可以配置你的缺省文本编辑器,Git在需要你输入一些消息时会使用该文本编辑器。缺省情况下,Git使用你的系统的缺省编辑器,这通常可能是vi 或者 vim。如果你想使用一个不同的文本编辑器,例如Emacs,你可以做如下操作:

$ git config –global core.editor emacs

2.3 检查你的设置(Checking Your Settings)

如果你想检查你的设置,你可以使用 git config –list 命令来列出Git可以在该处找到的所有的设置:

$ git config –list

你也可以查看Git认为的一个特定的关键字目前的值,使用如下命令 git config {key}:

$ git config user.name

2.4 获取帮助(Getting help)

如果当你在使用Git时需要帮助,有三种方法可以获得任何git命令的手册页(manpage)帮助信息:

$ git help <verb>

$ git <verb> –help

$ man git-<verb>

例如,你可以运行如下命令获取对config命令的手册页帮助:

$ git help config