git
git 简介和使用
git 命令
git status (-s)
vim CONTRIBUTING.md
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README
modified: CONTRIBUTING.md
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: CONTRIBUTING.mdgit rm (--cached)
git config --global alias.last 'log -1 HEAD'
git 分支
提交对象
首次提交
以后的提交
Git 的分支,其实本质上仅仅是指向提交对象的可变指针。
HEAD 的特殊指针。在 Git 中,它是一个指针,指向当前所在的本地分支(译注:将 HEAD 想象为当前分支的别名)。
合并
fast-forward
git checkout master
git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)直接指针右移, 没有需要解决的冲突
分支之间的合并
和之间将分支指针向前推进所不同的是,Git 将此次三方合并的结果做了一个新的快照并且自动创建一个新的提 交指向它。这个被称作一次合并提交,它的特别之处在于他有不止一个父提交。
解决冲突
如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修 改,Git 就没法干净的合并它们。
在你解决了所有文件里的冲突之后,对每个文件使用 git add 命令来将其标记为冲突已解决。一旦暂存这 些原本有冲突的文件,Git 就会将它们标记为冲突已解决。
远程分支
- git clone
- git fetch
git pull = git fetch + git merge
git fetch, git merge
git push
rebase
与 git merge 不同, 其实,还有一种方法:你可以提取在 C4 中引入的补丁和修改,然后在 C3 的基础上再应用一次。在 Git 中,这种 操作就叫做 变基。你可以使用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新 播放”一样。
它的原理是首先找到这两个分支(即当前分支 experiment、变基操作的目标基底分支 master)的最近共同祖 先 C2,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将当前分支指向目 标基底 C3, 最后以此将之前另存为临时文件的修改依序应用。
变基使得提交历史更加整洁
git 工具
- git show SHA-1
git 内部原理
git 基础
工作区
电脑里能看到的目录
版本库
.git
其中包含了 stage/index 暂存区, 即 git add 操作
git 数据库
.git 文件
$ ls -F1 |
description gitweb 程序使用, 无需关心
config 配置
info 包含一个全局性排除文件
hooks 包含客户端或服务端的钩子脚本
objects 存储所有数据内容
refs 存储指向数据(分支)的提交对象的指针
HEAD 只是目前被检出的分支
index 保存暂存区信息
objects
数据对象
git init 用于创建一个空的git仓库,或重置一个已存在的git仓库
git hash-object git底层命令,用于向Git数据库中写入数据
echo "version 1" | git hash-object -w --stdin
83baae61804e65cc73a7201a7252750c76066a30
find .git/objects/ -type f
.git/objects/83/baae61804e65cc73a7201a7252750c76066a30echo "version 1" > file.txt
git hash-object -w file.txt
83baae61804e65cc73a7201a7252750c76066a30git cat-file git底层命令,用于查看Git数据库中数据
git cat-file -p 83baa
version 1问题:
第一,无法记录文件名的变化;
第二,无法记录文件夹的变化;
第三,记忆每一个版本对应的hash值无聊且乏味且不可能;
第四,无法得知文件的变更时序;
第五,缺少对每一次版本变化的说明。
树对象
Git利用树对象(tree object)解决文件名保存的问题,树对象也能够将多个文件组织在一起。
- git update-index git底层命令,用于创建暂存区
- git ls-files --stage git底层命令,用于查看暂存区内容
- git write-tree git底层命令,用于将暂存区内容写入一个树对象
前两个命令都是对暂存区操作, 第三个则会在 objects 里创建一个树对象
find .git/objects -type f |
查看内容
git cat-file -t 391a4e # -t 类型 |
commit 对象
commit对象能够帮你记录什么时间,由什么人,因为什么原因提交了一个新的版本,这个新的版本的父版本又是谁。
- git commit-tree git 底层命令, 用来创建提交对象
git write-tree |
git 工作原理
Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remote:远程仓库
初次使用 git
$ git config --global user.name "John Doe" |
git config 一个用来配置 git 的工具
--global 默认全局, 如果要针对特定 git 仓库修改, 不要使用 global
1.git 回退
$ git status |
你可以发现,Git会告诉你,git checkout -- file
可以丢弃工作区的修改:
$ git checkout -- readme.txt |
总之,就是让这个文件回到最近一次git commit
或git add
时的状态。
- Git同样告诉我们,用命令
git reset HEAD <file>
可以把暂存区的修改撤销掉(unstage),重新放回工作区:
$ git reset HEAD readme.txt |
-u参数:关联本地分支和远程分支
git merge $branch_name 如果有冲突要手动解决(一般是两个分支有不同的提交内容)
git branch -d $branch_name 删除分支
git rm --cached $doc_name 删除文件(会影响到远程
git branch --set-upstream-to=origin/$name
git branch -vv 查看本地分支和远程分支的对应关系
git pull <远程主机名> <远程分支名>:<本地分支名>
fatal: refusing to merge unrelated histories
--allow-unrelated-histories
CRLF和LF
crlf:carriage return line feed回车换行
lf:line feed 换行
reason:
When you view changes in a file, Git handles line endings in its own way.Since you're collaborating on projects with Git and GitHub, Git mightproduce unexpected results if, for example, you're working on a Windows machine,and your collaborator has made a change in OS X.
CRLF->Windows-style
LF->Unix Style
CR->Mac Style
CRLF表示句尾使用回车换行两个字符(即我们常在Windows编程时使用""换行)
LF表示表示句尾,只使用换行.
CR表示只使用回车.