下载传送门
Git国内下载地址
下载好对应的版本,一直一下步,就可以了。
安装完后,鼠标右键桌面 打开Git Bash Here
进入控制台界面,输入git --version
查看安装的版本。
配置用户名
git config --global user.name "填你的名字"
配置邮箱
git config --global user.email [email protected]
查看配置
git config --list
git有三个级别的配置
其中
–global 的配置级别是用户
–system为系统配置级别
如果不写,–xxx这个参数,则配置后,仅仅对当前项目起作用。
git两大主线
1.区域
工作区(编写代码的地方)
暂存区(代码做了增删改查后,保存下来的地方,还未提交)
版本库(完善了很多模块后,提交上去,变成一个新的版本,管理版本的地方)
2.对象
git对象
树对象
提交对象
在桌面随便建一个文件夹,然后点开文件夹,然后右键进入Git Bash Here
进入控制台程序后,输入一下命令,进行git仓库初始化
git init
运行后生成如下文件
hooks:用于编写提交代码前后需要触发的事件,比如提交前,验证代码格式
info:包含一个全局性排除文件(哪些文件不需要git管理了,就丢进去)
logs:保存日志信息
objects:目录存储所有数据内存
refs:目录存储指向数据(分支)的提交对象的指针
config:文件包含项目特有的配置选项
description:用来显示对仓库的描述信息
HEAD :文件指示目前被检出的分支
index:文件保存暂存区信息
clear:清除屏幕
echo ‘test content’:往控制台输出信息
echo ‘hah’ > test.txt :创建文件,把输出信息,保存到txt文件中。
ll:将当前目录下的 子文件和子目录平铺在控制台
find 目录名:将对应目录下的子孙文件和子孙目录平铺在控制台
find 目录名 -type f :将对应目录下的文件平铺在控制台
rm 文件名 :删除文件
mv 源文件 重命名文件 :重命名
cat 文件的url :查看对应文件的内容
vim 文件的url(在引文模式下)
按 i 进入插入模式 进行文件的编辑
按 esc 键 退出编辑模式后 按 : 键 进行命令的执行
q! 强制退出(不保存)
wq 保存退出
set nu 设置行号
Git的核心部分是一个简单的键值对数据库。你可以向该数据库插入任意类型的内容,它会返回一个键值,通过该键值可以在任意时刻再次检索内容。
向数据库写入内容 并返回对应键值
命令
echo ‘test content’ t | git hash-object -w --stdin
-w 选项指示 hash-object 命令存储数据对象;如不指定该选项,则该命令只返回对应的键值
–stdin(standard input)选项指示该命令从标准输入读取内容;若不指定该选项,则需要在命令尾部给出存储文件的路径
git hash-object -w 文件路径
存文件
git hash-object 文件路径
返回对应文件键值
返回:
该命令输出一个长度40个字符的校验,是一个SHA-1哈希值
查看Git是如何存储数据的
命令:
find .git/objects -type f
存入文件命名规则:哈希前2字符为目录名,后38位为文件名
根据减值拉取数据
命令
git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
-p 选项指示该命令自动判断内容类型,并为我们显示格式友好的内容
返回:
对应文件的内容
对一个文件进行简单的版本控制
创建一个新文件并将其内容存入数据库
命令:
echo ‘version 1’ >test.txt
git hash-object -w test.txt
返回:
查看git存储的对象类型
命令:
$ git cat-file -t d670460b4b4aece5915caf5c68d12f560a9fe3e4
返回:blob类型
向文件写入新内容,并再次将其存入数据库
命令
echo ‘version 2’>test.txt
git hash-object -w test.txt
接下来要探讨的 Git 对象类型是树对象(tree object),它能解决文件名保存的问题,也允许我们将多个文件组织到一起。 Git 以一种类似于 UNIX 文件系统的方式存储内容,但作了些许简化。 所有内容均以树对象和数据对象的形式存储,其中树对象对应了 UNIX 中的目录项,数据对象则大致上对应了 inodes 或文件内容。 一个树对象包含了一条或多条树对象记录(tree entry),每条记录含有一个指向数据对象或者子树对象的 SHA-1 指针,以及相应的模式、类型、文件名信息。一个树对象也可以包含另一个树对象
构建树对象
我们可以通过 update-index;write-tree ; read-tree等命令来构建树对象并塞入到暂存区
构建之前 查看一下暂存区有哪些内容。
命令:
git ls-files -s
操作
创建一个暂存区
命令:
git update-index --add --cacheinfo 100644 e028ca8d1dfdfad8e058f854d5038725a5451a09 t.txt
文件模式为
100644,表明这是一个普通文件
100755,表示一个可执行文件;
120000,表示一个符号链接。
–add 选项:
因为此前该文件并不在暂存区中 首次需要—add
–cacheinfo 选项:
因为将要添加的文件位于 Git 数据库中,而不是位于当前
目录下 所有需要—cacheinfo
接着生成树对象
命令:
git write-tree
将第一个树对象加入第二个树对象,使其成为新的树对象
命令:
git read-tree
–prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579
git write-tree
read-tree 命令,可以把树对象读入暂存区
另外查看树对象命令和查看git对象命令一样。
git cat-file -p 树对象哈希值
总结
我们可以认为树对象就是我们项目的快照
树对象生成完后,其实就对应的把当前项目版本写入了git对象数据库。可以简单理解 一个树对象就是一个项目版本 一个git对象就是一个文件版本。一个树对象可以用由多个文件对象组成。从暂存区生成完后树对象,暂存区数据是不会清空的。
如果你更新到暂存区的文件名和原本存在暂存区的文件名一致,则会进行覆盖。
暂存区里可以写入多个文件对象,然后通过git write-tree命令生成树对象,也就是对应的版本对象到数据库。
我们可以通过调用 commit-tree 命令创建一个提交对象,为此需要指定一个树
对象的 SHA-1 值,以及该提交的父提交对象(如果有的话 第一次将暂存区做快
照就没有父对象)
创建提交对象
**echo ‘描述信息’ | git commit-tree 树对象哈希值
返回:
fdf4fc3344e67ab068f836878b6c4951e3b15f3d
**
查看提交对象
git cat-file -p fdf4fc3344e67ab068f836878b6c4951e3b15f3d
返回:
tree 树对象哈希值
author wjc <邮箱> 1243
committer wjc <邮箱> 1243
描述信息
接着,我们将创建另两个提交对象,它们分别引用各自的上一个提交(作为其
父提交对象):
echo ‘second commit’ | git commit-tree 0155eb -p fdf4fc3
cac0cab538b970a37ea1e769cbbde608743bc96d
echo ‘third commit’ | git commit-tree 3c4e9c -p cac0cab
1a410efbd13591db07496601ebc7a059dd55cfe9
最终生成如下图结构:
注意
git commit-tree 不但生成提交对象 而且会将对应的快照(树对象)提交到本地库中
记录每次更新到仓库
工作目录下面的所有文件都不外乎这两种状态:已跟踪 或 未跟踪
已跟踪的文件是指本来就被纳入版本控制管理的文件,在上次快照中有它
们的记录,工作一段时间后,它们的状态可能是已提交,已修改或者已暂存
所有其他文件都属于未跟踪文件。它们既没有上次更新时的快照,也不在
当前的暂存区域。
初次克隆某个仓库时,工作目录中的所有文件都属于已跟踪文件,且状态
为已提交;在编辑过某些文件之后,Git 将这些文件标为已修改。我们逐步把
这些修改过的文件放到暂存区域,直到最后一次性提交所有这些暂存起来的文
件。
检查当前文件状态
命令:git status
作用:确定文件当前处于什么状态
未跟踪文件
如果创建一个新文件 README,保存退出后运行 git status 会看到该文件出现
在未跟踪文件列表中:
On branch master
Untracked files:
(use “git add …” to include in what will be committed)
README
nothing added to commit but untracked files present (use “git add” to
track)
在状态报告中可以看到新建的 README 文件出现在“Untracked files”下
面。未跟踪的文件意味着 Git 在之前的快照(提交)中没有这些文件;Git 不
会自动将之纳入跟踪范围,除非你明明白白地告诉它“我需要跟踪该文件”,因
而不用担心把临时文件什么的也归入版本管理。
跟踪新文件(暂存)
命令:git add 文件名
作用:跟踪一个新文件
再次运行 git status 命令,会看到 README 文件已被跟踪,并处于暂存
状态
Changes to be committed:
(use “git reset HEAD …” to unstage)
new file: README
只要在 “Changes to be committed” 这行下面的,就说明是已暂存状态。
如果此时提交,那么该文件此时此刻的版本将被留存在历史记录中。在 git
add 后面可以指明要跟踪的文件或目录路径。如果是目录的话,就说明要递归
跟踪该目录下的所有文件。(译注:其实 git add 的潜台词就是把目标文件快
照放入暂存区域,也就是 add file into staged area,同时未曾跟踪过的文件标
记为已跟踪。)
暂存已修改文件
现在 README 文件都已暂存,下次提交时就会一并记录到仓库。假设此时,
你想要在 README 里再加条注释,重新编辑存盘后,准备好提交。不过且慢,再
运行 git status 看看:
On branch master
Changes to be committed:
(use “git reset HEAD …” to unstage)
new file: README
Changes not staged for commit:
(use “git add …” to update what will be committed)
(use “git checkout – …” to discard changes in working directory)
modified: README
README 文件出现了两次!一次算已修改,一次算已暂存,这怎么可能呢?
好吧,实际上 Git 只不过暂存了你运行 git add 命令时的版本,如果现在提交,那
么提交的是添加注释前的版本,而非当前工作目录中的版本。所以,运行了 git
add 之后又作了修订的文件,需要重新运行 git add 把最新版本重新暂存起来:
$ git add README
$ git status
On branch master
Changes to be committed:
(use “git reset HEAD …” to unstage)
new file: READM
查看已暂存和未暂存的更新
实际上 git status 的显示比较简单,仅仅是列出了修改过的文件,如果要
查看具体修改了什么地方,可以用 git diff 命令.这个命令它已经能解决我们
两个问题了:当前做的哪些更新还没有暂存?有哪些更新已经暂存起来准备
好了下次提交?
提交更新
当暂存区域已经准备妥当可以提交时,在此之前,请一定要确认还有什么修改
过的或新建的文件还没有 git add 过,否则提交的时候不会记录这些还没暂存起来
的变化。所以,每次准备提交前,先用 git status 看下,是不是都已暂存起来了,
然后再运行提交命令 git commit
命令:git commit
注意:这种方式会启动文本编辑器以便输入本次提交的说明
默认的提交消息包含最后一次运行 git status 的输出,放在注释行里,
另外开头还有一空行,供你输入提交说明。你完全可以去掉这些注释行,
不过留着也没关系,多少能帮你回想起这次更新的内容有哪些。
另外也可以用 -m 参数后跟提交说明的方式,在一行命令中提交更新:
命令:git commit –m “message xxx”
提交时记录的是放在暂存区域的快照,任何还未暂存的仍然保持已修改状态,
可以在下次提交时纳入版本管理。每一次运行提交操作,都是对你项目作一次快照,
以后可以回到这个状态,或者进行比较
跳过使用暂存区域
尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁
琐。Git 提供了一个跳过使用暂存区域的方式,只要在提交的时候,给 git
commit 加上 -a 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,
从而跳过 git add 步骤
git commit -a
移除文件
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中注册删除(确切地说,
是在暂存区域注册删除),然后提交。可以用 git rm 命令完成此项工作,并连带
从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
文件改名
git mv file.from file.to
查看历史记录
git log
git log 参数
git log --pretty=oneline
git log --oneline
几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工
作从开发主线上分离开来,以免影响开发主线。 在很多版本控制系统中,这是一个
略微低效的过程——常常需要完全创建一个源代码目录的副本。对于大项目来说,这
样的过程会耗费很多时间。
而 Git 的分支模型极其的高效轻量的。是 Git 的必杀技特性,也正因为这一特性,使
得 Git 从众多版本控制系统中脱颖而出
创建分支
命令:git branch
作用:
为你创建了一个可以移动的新的指针。 比如,创建一个 testing 分
支:git branch testing。这会在当前所在的提交对象上创建一个指针
注意:
git branch 分支名 创建 一个新分支,并不会自动切换到新分支中去
git branch 不只是可以创建与删除分支。 如果不加任何参数运行它,
会得到当前所有分支的一个列表
git branch -d name
删除分支
尝试使用 git branch -d 命令删除在这个列表中的分支时会失败。
如果真的想要删除分支并丢掉那些工作,可以使用 -D 选项强制删
除它。
git branch -v
可以查看每一个分支的最后一次提交
git branch name commitHash
新建一个分支并且使分支指向对应的提交对
查看项目分叉历史
git log --oneline --decorate --graph --all
在主分支创建一个test分支并切换到该分支上
git checkout -b test
1.快进(fast-forward)合并(如果新建的分支只是修改主分支的BUG 建议使用该方法合并)
你可以运行你的测试,确保你的修改是正确的,然后将其合并回你
的 master 分支来部署到线上。 你可以使用 git merge 命令来达到上
述目的
git checkout master
git merge hotfix
在合并的时候,有时候会出现"快进(fast-forward)"这个词。 由于当
前 master 分支所指向的提交是你当前提交的直接上游,所以 Git 只是简
单的将指针向前移动。 换句话说,当你试图合并两个分支时,如果顺着一个
分支走下去能够到达另一个分支,那么 Git 在合并两者的时候,只会简单的
将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分
歧——这就叫做 “快进(fast-forward)
PS:言外之意,就是你主分支上出现了Bug,我开启一个分支去修改这个Bug,修改好后,因为只是给主分支打补丁,涉及不到其他额外模块,所以指针直接指向了你那个分支,并将它变为最新的主分支。
2.典型合并(就是如果合并之后有冲突,把冲突该解决,然后重新提交)
冲突
有时候合并操作不会如此顺利。 如果你在两个不同的分支中,对同一个
文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们。 如果你
对 #53 问题的修改和有关 hotfix 的修改都涉及到同一个文件的同一
处,在合并它们的时候就会产生合并冲突
此时 Git 做了合并,但是没有自动地创建一个新的合并提交。 Git 会暂
停下来,等待你去解决合并产生的冲突。 你可以在合并冲突后的任意时刻
使用 git status 命令来查看那些因包含合并冲突而处于未合并(unmerged)
状态的文件
任何因包含合并冲突而有待解决的文件,都会以未合并状态标识出来。
<<<<<<< HEAD:index.html
分支本质
Git 的分支,其实本质上仅仅是指向提交对象的可变指针。 Git 的默认分支
名字是 master。 在多次提交操作之后,你其实已经有一个指向最后那个提交对
象的 master 分支。 它会在每次的提交操作中自动向前移动。
注意
Git 的 “master” 分支并不是一个特殊分支。 它就跟其它分支完全没有区别。 之所
以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它,并且大多数
人都懒得去改动它。
有时,当你在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状
态,而这时你想要切换到另一个分支做一点别的事情。 问题是,你不想仅仅因为
过会儿回到这一点而为做了一半的工作创建一次提交。 针对这个问题的答案是
git stash 命令
git stash 命令会将未完成的修改保存到一个栈上,而你
可以在任何时候重新应用这些改动(git stash apply)
git stash list:查看存储
git stash apply stash@{2}
如果不指定一个储藏,Git 认为指定的是最近的储藏
git stash pop 来应用储藏然后立即从栈上扔掉它
git stash drop 加上将要移除的储藏的名字来移除它
Git 并不会在你输入部分命令时自动推断出你想要的命令。 如果不想每次都输入
完整的 Git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名。
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
当要输入 git commit 时,只需要输入 git ci
撤销&重置
撤销
git commit –amend
命令: git commit --amend
作用:
这个命令会将暂存区中的文件提交。
如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执
行了此命令),那么快照会保持不变,而你所修改的只是提交信息
如果你提交后发现忘记了暂存某些需要的修改,可以像下面这样操作
git commit -m ‘initial commit’
git add forgotten_file
git commit –amend
最终你只会有一个提交 - 第二次提交将代替第一次提交的结果
git reset
命令:git reset HEAD 文件名
作用:将文件从暂存区中撤回到工作目录
git checkout
命令:git checkout – 文件名
作用:将在工作目录中对文件的修改撤销
注意:
git checkout – [file] 是一个危险的命令,这很重要。 你对那个文件做的任
何修改都会消失 - 你只是拷贝了另一个文件来覆盖它。除非你确实清楚不想要那个文件了,
否则不要使用这个命令
一个完整的流程