《Pro Git》笔记2:Git基础操作
第二章 Git基础
Git基础包括:版本库的创建和获取,文件添加修改提交等基本操作,状态查询,远程版本库管理和同步,打标签。
1.取得项目的Git版本库
基于Git的工作流要以Git版本库为基础,即可以直接创建一个新的本地版本库,也可以将一个已有的远程版本库克隆到本地。
(1)创建新的本地版本库
在一个目录中执行git init命令,会在该目录中建立.git的目录,里面存放了Git需要的所有数据和资源,自然包括一个空的本地版本库。
git init
然后就是向这个本地版本库中存放版本数据了。先使用git add命令添加要追踪的文件,将其纳入版本控制(暂存)。在使用git commit命令提交(将新追踪的文件存入版本库)。这样就创建好了一个项目的本地的版本库。
$ git add *.c
$ git add README
$ git commit -m 'initial project version'
(2)将已有版本库克隆到本地
克隆使用命令git clone。要注意clone是拉取包含了所有修订版本的整个远程版本库到本地,;而checkout只是把本地版本库中的单个修订版本取出来放到工作区里。远程版本库地址可能的协议有git://,http://,https://, SSH (user@server:/path.git)
$ git clone git://github.com/schacon/grit.git (自动创建grit目录存放版本库)
$ git clone git://github.com/schacon/grit.git myGrit (自定义项目目录的名字)
2.将修改保存到版本库
上一篇文章中提到了Git中记录文件变更的三个阶段:修改,暂存,提交。实际在工作目录中,所有文件都可以分为未追踪和已追踪两大类。已追踪文件又有未更新(文件系统状态和git数据不一致),未修改,已修改,已暂存等状态。其实还有一类会被Git无视的已忽略状态的文件和目录。使用git status命令可以查看文件所处的状态。
git status 只能在Git本地版本库目录(包含.git子目录)或其子目录下执行
(1)最初始时,工作目录是干净的目录,无未追踪文件,已追踪项目也无任何修改。状态如下:
$ git status
On branch master
nothing to commit, working directory clean
(2)添加新的文件后,显示出未追踪项目
$ echo readme>README
$ git status
On branch master
Untracked files: (还未追踪的项目)
(use "git add <file>..." to include in what will be committed)
README
nothing added to commit but untracked files present (use "git add" to track)
(3)追踪还未版本化的文件,文件从未追踪变为已暂存状态
$ git add README (如果添加目录,自动递归添加目录下所有项目)
$ git status
On branch master
Changes to be committed: (已经暂存的项目)
(use "git reset HEAD <file>..." to unstage)
new file: README
(4)修改先前已版本化的文件,文件变成已修改未暂存状态
$echo bbb>benchmarks.rb
$ git status
# On branch master
# Changes to be committed:(已经暂存的项目)
# (use "git reset HEAD <file>..." to unstage)
# new file: README
# Changes not staged for commit: (已修改还未暂存的项目)
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
# modified: benchmarks.rb
(5)暂存已修改的文件,也是用git add命令
$ git add benchmarks.rb
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
# new file: README
# modified: benchmarks.rb
(6)再次修改已暂存的文件,该文件在暂存区会保留一份再次修改前的版本(提交操作的会提交暂存的这一版本),工作目录中同时出现一份再次修改后的版本。
$ echo ccc>benchmarks.rb
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
# new file: README
# modified: benchmarks.rb (暂存前修改过的版本,下次提交时会被提交)
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
# modified: benchmarks.rb (暂存后再修改的版本,下次提交时不会被提交)
(7)再次暂存修改,文件从已修改变为已暂存状态,并且将暂存区中前一次暂存的版本覆盖掉。
$ git add benchmarks.rb
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
# new file: README
# modified: benchmarks.rb
(8)忽略某些对象。(如自动生成的临时文件,编译的中间文件等)。可以在多处配置忽略模式。
方法一:在项目根目录中创建一个.gitignore文件,其中加入要忽略的文件模式即可。(所有空或#开头的行被忽略,支持标准glob模式,/结尾表示目录,!表示忽略指定模式以外的项目)。此.gitignore会提交到版本库,所有人都有效。后面的其他方法只在本地有效。
方法二:全局的.gitignore文件。
方法三:通过git config --global core.excludesfile ~/.gitignoreglobal指定其他忽略文件。
方法四: 编辑项目目录里的.git/info/exclude。
glob模式(shell使用的简化正则表达式):*(0个或多个任意字符),[abc](括号中任何一个字符),?(一个任意字符),[0-9a-zA-Z](范围内任意一个字符)
.gitignore文件示例:
*.[oa] #忽略.o或.a结尾的文件
!lib.a #上一条规则中,lib.a除外
*~ #忽略~结尾的编辑器自动保存副本文件
/TODO #仅忽略根目录下的TODO文件,不包括subdir/TODO
tmp/ #忽略tmp目录下的所有项目
doc/*.txt #忽略/doc/notes.txt,但不忽略doc/server/arch.txt
(9)比较文件不同版本的具体差异(git diff命令),使用文件补丁格式显示差异。
git diff [PATH] #比较工作目录中版本和暂存版本的差异,(修改了还未暂存的变更)
git diff --cached|--staged [PATH] #比较暂存版本和上次提交版本的差异,(暂存了还未提交的变更)
(10)提交更新(git commit命令),不使用-a选项时提交前先确认修改内容都已暂存。
git commit #这种方式会调用core.editor配置变量中设置的编辑器,让用户输入提交说明,(编辑器中会显示注释掉的提示信息:git status的结果,带-v选项还有git diff的结果,用户输入提交说明并关闭编辑器后所有的注释和空行都被移除)。
git commit -m <提交说明> #提交说明中包含空格时,要用引号引起来
git commit -a -m <提交说明> #加上-a选项,git会自动把已追踪过的文件修改暂存起来一起提交,不需要手动暂存(git add)。
git commit -am <提交说明> #同上
提交后还会回显提交到的分支,新提交的SHA1校验和,改动统计。
$ git commit -m "Story 182: Fix benchmarks for speed"
[master]: created 463dc4f: "Fix benchmarks for speed"
2 files changed, 3 insertions(+), 0 deletions(-)
create mode 100644 README
(11)移除文件(从追踪文件清单和版本库中移除)。从在暂存区删除(即添加删除操作到暂存区),提交后版本库中就删除了。使用git rm同时移除追踪并删除文件。如果使用系统rm命令删除了文件,会出现不一致的情况,仍需要用git rm将其从暂存区删除。下面的<PATH>也可以为glob模式。
git rm <PATH> #直接删除暂存过的文件会报错。
git rm -f <PATH> #同时删除暂存的版本,会丢失暂存的修改内容。
git rm --cached <PATH> #从暂存区和版本库中删除,保留工作目录中的。
$rm grit.gemspec
$ git status
# On branch master
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
# deleted: grit.gemspec
#no changes added to commit (use "git add" and/or "git commit -a")
$ git rm grit.gemspec
rm 'grit.gemspec'
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
# deleted: grit.gemspec
如果要删除的文件已经被暂存。会提示
$git rm test.txt
error: the following file has changes staged in the index
test.txt
(use --cached to keep the file, or -f to force removal)
(12)glob模式的扩展。git命令中的文件或目录参数也可以使用glob模式,shell命令行也会自动展开一些通配模式,要注意区分。
git rm log/*.log #未加反斜杠,shell扩展命令,仅仅删除log目录下的文件,不会递归。
git rm log/\*.log #加反斜杠,屏蔽shell扩展,git负责扩展,递归删除log目录下的所有.log文件。
git rm \*~ #递归删除当前目录及其子目录中所有~结尾的文件。
(13)移动文件和重命名。git不追踪移动和重命名操作,可以用mv ,git rm, git add三条命令完成重命名或移动(这三个命令可以使用git mv一条命令代替),git会将这些操作的结果都自动识别为重命名。
$ mv README.txt aaa/README
$ git rm README.txt
$ git add aaa/README
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
# renamed: README.txt -> aaa/README
$ git mv README.txt README
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
# renamed: README.txt -> README
3.查看提交历史
(1)输出命令和格式
git log #按提交时间从新到老列出所有提交记录,默认显示SHA1,作者名字和邮箱,提交时间,提交说明。
-p 按补丁格式额外显示内容差异(git diff)
--stat 额外显示每个文件的变更统计数据和总体变更统计数据
--pretty=oneline(单行显示SHA1和说明)|short|full|fuller|format:"格式占位符" 选择或定制输出内容
格式占位符:作者和提交者不一定相同,提交者可能是版本库管理者,将作者私有分支中提交合并到主分支。
%H | SHA1 | %h | 简短SHA1 | %T | 树SHA1 | %t | 树简短SHA1 |
%P | 父对象SHA1 | %p | 父对象简短SHA1 | %an | 作者名字 | %ae | 作者email |
%ad | 作者修改日期 (可用-date定制格式) |
%ar | 作者修订日期,多久前 | %cn | 提交者名字 | %ce |
提交者email |
%cd | 提交日期 | %cr | 提交日期,多久前 | %s | 提交说明 |
--graph 输出能够在一行显示时(使用--pretty选项值为online或format),每行开头显示提交所在分支及其分化衍合图形。
--shortstat 只显示总体变更统计
--name-only 仅在提交信息后显示已修改的文件清单
--name-status 显示新增,修改,删除的文件清单
--abbrev-commit 显示简短SHA1
--relative-date 显示相对时间
(2)输出过滤,过滤条件可以组合
-<数字N> 显示最近的N次提交
-- <PATH> 按提交涉及的文件过滤,放在最后,--用于分隔其他参数,如果无其他参数--可以省略,--与<PATH>直接要有空格
--since|after|until|before = 2.weeks |"2008-01-15" |"2 years 1day 3minutes ago"
--author=<AUTHORNAME> 只显示某个作者的提交
--grep =<DESC> 显示提交说明满足<DESC>条件的提交
--committer=<COMMITTER> 按提交者过滤
--no-merges 还未合并的
例如:显示2008年10月gitster提交的但未合并的涉及test/目录下文件的提交
$ git log --pretty="%h:%s" --author=gitster --since="2008-10-01" --before="2008-11-01" --no-merges -- test/
5610e3b - Fix testcase failure when extended attribute
acd3b9e - Enhance hold_lock_file_for_{update,append}()
f563754 - demonstrate breakage of detached checkout wi
d1a43f2 - reset --hard/read-tree --reset -u: remove un
51a94af - Fix "checkout --track -b newbranch" on detac
b0ad11e - pull: allow "git pull origin $something:$cur
(3)使用图形化工具查看历史,如gitk
(4)git show命令
(5)git blame命令
4.撤销操作
(1)修改最后一次提交。git commit加--amend选项,只修改上一次的提交,不会生成新的提交。
git commit --amend
git commit --amend -m <新提交说明>
(2)取消已经暂存的文件(git status命令中有提示说明)
git reset HEAD [-- ] <PATH> #-- 用于分隔其他参数,没其他参数可忽略
(3)取消对文件的修改(git status命令中有提示说明),会丢失还未提交的修改,谨慎使用
git checkout [-- ] <PATH> #会丢失修改内容,谨慎使用,-- 用于分隔其他参数,没其他参数可忽略
5.远程版本库同步
(1)查看远程版本库
git remote #只显示远程版本库名(git clone命令会自动创建并使用origin远程库)
git remote -v|--verbose #显示远程版本库名和地址
origin git://github.com/schacon/ticgit.git
(2)添加远程库
git remote add <远程版本库名> <版本库URL>
(3)抓取远程库数据,不会自动将数据合并到当前工作分支。
git fetch <远程版本库名> [分支] #抓取所有远程库独有的数据到本地
git pull <远程版本库名> <分支]> #抓取远程版本库某分支的数据到本地并合并到工作分支。
git pull #设置了某个分支跟踪远程库的分支后,可不带参数。git clone自动创建本地master分支跟踪远程maser分支。
git fetch -b #-b选项表示
(4)推送数据到远程版本库。需要服务器上的写权限。如果别人先推送过更新,需要先抓取到本地进行合并,然后才能推送成功。
git push [远程版本库名] [分支] #需要远程库的写权限。设置了分支跟踪后,可以不带参数。
(5)查看远程仓库信息
git remote show <远程版本库名>
$ git remote show origin
* remote origin
URL: git@github.com:defunkt/github.git
Remote branch merged with 'git pull' while on branch issues (pull自动追踪合并的分支)
issues
Remote branch merged with 'git pull' while on branch master (pull自动追踪合并的分支)
master
New remote branches (next fetch will store in remotes/origin) (还未同步到本地的分支)
caching
Stale tracking branches (use 'git remote prune') (同步到本地后在远程被删除的分支)
libwalker
walker2
Tracked remote branches (已追踪的远程分支)
acl
apiv2
dashboard2
issues
master
postgres
Local branch pushed with 'git push' (push默认推送的分支)
master:master
(6)删除远程版本库
git remote rm <远程版本库名>
(7)重命名远程版本库,重命名后所有远程分支名也会变化(如oldrepo/master变为newrepo/master)
git remote renmae <原远程库名> <新远程库名>
(8)清理在远程不存在的本地分支
git remote prune
6.打标签
标签是某个提交对象(或者说修订版本)的引用,直接引用提交对象的是轻量级标签,单独创建一个标签对象存储额外信息(校验和,标签名字,email,时间,标签说明等)的是含附注标签。标签可以使用GPG来签署或验证。
(1)列出和显示标签
git tag #显示已有标签,按字母顺序排序
git tag -l 'v1.4.2.*' #过滤标签
v1.4.2.1
v1.4.2.2
v1.4.2.3
v1.4.2.4
git show <标签名> #轻量级标签,只显示标签引用的提交对象信息,含附注标签还会显示标签对象自身信息(绿字)
tag v1.4
Tagger: Scott Chacon <schacon@gee-mail.com>
Date: Mon Feb 9 14:45:11 2009 -0800
my version 1.4 (标签说明)
commit 15027957951b64cf874c3557a0f3547bd83b3ff6
Merge: 4a447f7... a6b4c97...
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sun Feb 8 19:02:46 2009 -0800
Merge branch 'experiment' (提交说明)
(2)新建标签,可以指定版本号给特定版本打上标签
git tag <标签名> [<版本SHA1>] #创建轻量级标签
git tag -a <标签名> [<版本SHA1>] -m <标签说明> #创建含附注标签
(3)分享标签,必须手动推送。其他人克隆或拉取数据同步后就能看到。
git push <远程库名> <标签名> #推送指定标签
git push <远程苦命> --tags #推送全部标签
(4)签署与验证标签(签署需要私钥,验证需要公钥)
git tag -s <标签名> -m <标签说明> #签署
git show <标签名>
tag v1.5
Tagger: Scott Chacon <schacon@gee-mail.com>
Date: Mon Feb 9 15:22:20 2009 -0800
my signed 1.5 tag
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)
iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN+ZxLKggJQf0QYiQBwgySN
Ki0An2JeAVUCAiJ7Ox6ZEtK+NvZAj82/
=WryJ
-----END PGP SIGNATURE-----
commit 15027957951b64cf874c3557a0f3547bd83b3ff6
Merge: 4a447f7... a6b4c97...
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sun Feb 8 19:02:46 2009 -0800
Merge branch 'experiment'
git tag -v <标签名> #验证
object 883653babd8ee7ea23e6a5c392bb739348b1eb61
type commit
tag v1.4.2.1
tagger Junio C Hamano <junkio@cox.net> 1158138501 -0700
GIT 1.4.2.1
Minor fixes since 1.4.2, including git-mv and git-http with alternates.
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
gpg: Good signature from "Junio C Hamano <junkio@cox.net>"
gpg: aka "[jpeg image of size 1513]"
Primary key fingerprint: 3565 2A26 2040 E066 C9A7 4A7D C0C6 D9A4 F311 9B9A
7.技巧和窍门
(1)自动完成,输入git命令或选项时,有多个备选时按tab两次显示提示,唯一时按tab自动补全。
bash shell当前用户:Git源码中contrib/completion/git-completion.bash文件复制到~目录,改名为.git-completion.bash,修改.bashrc文件加入source ~/.git-completion.bash。
bash shell系统全局:Git源码中contrib/completion/git-completion.bash文件复制到/opt/local/bash_completion.d目录(Mac)或/etc/bash_completion.d目录(Linux)即可,bash启动时自动加载此目录中内容。
windows用msysGit,Git Bash中默认已配好自动完成脚本。
(2)Git命令别名
git config [--global|--system] alias.<别名> <原命令或命令参数片段>
git config --global alias.st status #可用git st代替git status
git config --global alias.unstage 'reset HEAD -- ' #取消暂存:git unstage fileA 等效于git reset HEAD [--] fileA
git config --global alias.last 'log -1 HEAD' #查看最后一次提交:git last等效于git log -1 HEAD
《Pro Git》笔记2:Git基础操作的更多相关文章
- Git 笔记三 Git的初步使用
Git 笔记三 Git的初步使用 在上一篇中,学习了如何配置Git环境,这一篇,开始学习Git的初步使用.Git的初步使用还是很简单的.总体上知道git init, git clone, git ad ...
- Git 笔记二-Git安装与初始配置
git 笔记二-Git安装与初始配置 Git的安装 由于我日常生活和工作基本上都是在Windows上,因此此处只说windows上的安装.Windows上的安装和其他程序一样,只需要到http://g ...
- Git 笔记一 Git简介
git 笔记一 什么是版本控制 所谓版本控制就是记录对文件的修改记录,这样以后就能回退到需要的 版本.比如你对一段代码进行了几次修改,有几次修改不想要了,如果 使用了版本控制,就可以回退到未做这些修改 ...
- 项目管理---git----快速使用git笔记(一)------git的简单介绍
最近svn代码管理服务器崩溃了,切换到git来运作. 经过几天的使用,感觉很不错. 尤其是代码合并到正式版本之前 可以对代码进行 code review. 这样能很好的保证团队的代码质量和一些重复代码 ...
- Git笔记:Git介绍和常用命令汇总
Git 是一个开源的分布式版本控制系统,与 CVS, Subversion 等不同,它采用了分布式版本库的方式,不需要服务器端软件支持. 工作流程 Git 的工作流程大致如下: 克隆 Git 资源作为 ...
- 项目管理---git----快速使用git笔记(二)------git的本地安装
下载安装包 在使用Git前我们需要先安装 Git.Git 目前支持 Linux/Unix.Solaris.Mac和 Windows 平台上运行. Git 各平台安装包下载地址为:http://git- ...
- (2.2)学习笔记之mysql基础操作(登录及账户权限设置)
本系列学习笔记主要讲如下几个方面: 本文笔记[三:mysql登录][四:账户权限设置][五:mysql数据库安全配置] 三.mysql登录 常用登录方式如下: 四.账户权限设置 (4.1)查看用户表, ...
- (2.3)学习笔记之mysql基础操作(表/库操作)
本系列学习笔记主要讲如下几个方面: 本文笔记[六:表操作--线上可以直接删除表吗?] 附加:库操作 [1]创建制定字符集的数据库 需求描述: 在创建DB的时候指定字符集. 操作过程: 1.使用crea ...
- 11-numpy笔记-莫烦基础操作1
代码 import numpy as np array = np.array([[1,2,5],[3,4,6]]) print('-1-') print('数组维度', array.ndim) pri ...
- Git知识总览(一) 从 git clone 和 git status 谈起
本篇博客是整理git相关知识的第一篇,因为之前一直是用SourceTree对Git的命令行操作用的不是特别熟,于是乎过了一遍ProGit(链接:https://git-scm.com/book/zh/ ...
随机推荐
- 【读书笔记】读《编写高质量代码—Web前端开发修炼之道》 - JavaScript原型继承与面向对象
JavaScript是基于原型的语言,通过new实例化出来的对象,其属性和行为来自于两部分,一部分来自于构造函数,另一部分是来自于原型.构造函数中定义的属性和行为的优先级比原型中定义的属性和优先级高, ...
- 一、HTML和CSS基础--网页布局--实践--固定层效果
absolute和fixed的相同点: 第一,完全脱离标准文档流 第二,未设置偏移量时,都定位在父元素的左上角 absolute和fixed的不同点: 第一.当设置偏移量时,偏移参照基准不同 abso ...
- .NET的堆和栈01,基本概念、值类型内存分配
当我们对.NET Framework的一些基本面了解之后,实际上,还是很有必要了解一些更底层的知识.比如.NET Framework是如何进行内存管理的,是如何垃圾回收的......这样,我们才能写出 ...
- Java中Json用法
首先导入json.jar,非常简单看过代码就明白怎么用了 package cn.mylucene; import java.util.HashMap; import java.util.Map; im ...
- poj 1935(树形dp)
题目链接:http://poj.org/problem?id=1935 思路:首先我们考虑从源点出发到所有自己想要经过的点然后在回到源点sum,显然每条边都必须经过源点(这个我们可以一次dfs求出), ...
- cocos2dx游戏开发——微信打飞机学习笔记(八)——EnemyLayer的搭建
一.创建文件= = EnemyLayer.h EnemyLayer.cpp Ps:我绝对不是在凑字数~. 二.How to do? (1)一些宏 ...
- 基于C#语言利用Microsoft.office.introp.excel操作Excel总结
终于解决了质量评估测试软件在任意装有excel(2010以下版本)的电脑上正常使用的问题!!!!!!!!!! 可到http://www.microsoft.com/en-sa/download/con ...
- 【JUnit 报错】java.lang.IncompatibleClassChangeError
使用Junit 测试spring时候报错: java.lang.IncompatibleClassChangeError: class org.springframework.core.LocalVa ...
- python 类的初始化
虽然我们可以自由地给一个实例绑定各种属性,但是,现实世界中,一种类型的实例应该拥有相同名字的属性.例如,Person类应该在创建的时候就拥有 name.gender 和 birth 属性,怎么办? 在 ...
- 简单几何(点与线段的位置) POJ 2318 TOYS && POJ 2398 Toy Storage
题目传送门 题意:POJ 2318 有一个长方形,用线段划分若干区域,给若干个点,问每个区域点的分布情况 分析:点和线段的位置判断可以用叉积判断.给的线段是排好序的,但是点是无序的,所以可以用二分优化 ...