git备忘录
“origin” 并无特殊含义
远程仓库名字 “origin” 与分支名字 “master” 一样,在 Git 中并没有任何特别的含义一样。 同时 “master” 是当你运行 git init 时默认的起始分支名字,原因仅仅是它的广泛使用,“origin” 是当你运行 git clone 时默认的远程仓库名字。 如果你运行 git clone -o booyah,那么你默认的远程分支名字将会是 booyah/master。
git起步:
-
git 特点
- 直接记录快照,而非差异比较, Git 更像是一个小型的文件系统
- 近乎所有操作都是本地执行
- Git 保证完整性 SHA-1 散列(hash,哈希)
- Git 一般只添加数据
-
三种状态
-
已提交(committed)、已修改(modified)和已暂存(staged)
-
Git 仓库、工作目录以及暂存区域。
-
基本的 Git 工作流程如下:
-
在工作目录中修改文件。
-
暂存文件,将文件的快照放入暂存区域。 add
-
提交更新,找到暂存区域的文件,将快照永久性存储到 Git 仓库目录。 commit
-
-
-
配置 config
-
/etc/gitconfig 文件: 包含系统上每一个用户及他们仓库的通用配置。 如果使用带有 --system 选项的 git config 时,它会从此文件读写配置变量。
-
~/.gitconfig 或 ~/.config/git/config 文件:只针对当前用户。 可以传递 --global 选项让 Git 读写此文件。
-
当前使用仓库的 Git 目录中的 config 文件(就是 .git/config):针对该仓库
** 每一个级别覆盖上一级别的配置,所以 .git/config 的配置变量会覆盖 /etc/gitconfig 中的配置变量。 **
用户信息 $ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com $ git config --list $ git config user.name
-
-
$ git help config
git基础:
- 本地创建
初始化, 创建。git目录
$ git init
$ git add 跟踪
$ git commit -a -m 'initial project version'
- 远程clone
git clone https://github.com/libgit2/libgit2 mylibgit
Git 支持多种数据传输协议。 上面的例子使用的是 https:// 协议,不过你也可以使用 git:// 协议或者使用 SSH 传输协议,比如 user@server:path/to/repo.git
-
基本命令
-
git status
Untracked files 未add, 根据需求是否git add Changes to be committed: 已跟踪,且已暂存状态 Changes not staged for commit: 已跟踪, 未暂存 add
* git status -s ``` $ git status -s M README 修改了当未放入暂存区 M在后 MM Rakefile 放入暂存区后又修改了, 但未再一次放入暂存区 A lib/git.rb 新添加到暂存区的跟踪文件 M lib/simplegit.rb 修改了且放入暂存区 M在前 ?? LICENSE.txt 未跟踪 ``` * 忽略文件, 不出现在Untracked files中 <https://github.com/github/gitignore> ``` 创建.gitignore 的文件 文件 .gitignore 的格式规范如下: 所有空行或者以 # 开头的行都会被 Git 忽略。 可以使用标准的 glob 模式匹配。 匹配模式可以以(/)开头防止递归。 匹配模式可以以(/)结尾指定目录。 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反 ``` 在git中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改根目录中 .gitignore 文件的方法(如无,则需自己手工建立此文件)。这个文件每一行保存了一个匹配的规则例如: ``` # 此为注释 – 将被 Git 忽略 *.cs # 忽略所有 .cs 结尾的文件 !ABC.cs # 但 ABC.cs 除外 /BLL # 仅仅忽略项目根目录下的 BLL 文件,不包括 subdir/BLL build/ # 忽略 build/ 目录下的所有文件 doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt ``` 规则很简单,不做过多解释,但是有时候在项目开发过程中,突然心血来潮想把某些目录或文件加入忽略规则,按照上述方法定义后发现并未生效,原因是.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交: ``` git rm -r --cached . git add . git commit -m 'update .gitignore' ``` * git diff * 要查看尚未暂存的文件更新了哪些部分,不加参数直接输入 git diff * 若要查看已暂存的将要添加到下次提交里的内容 git diff --staged 或 git diff --cached * 请注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂存了所有更新过的文件后,运行 git diff 后却什么也没有,就是这个原因。 * git diff HEAD -- readme.txt 查看工作区和版本库里面最新版本的区别 * git commit 每次准备提交前,先用 git status 看下,是不是都已暂存起来了, 然后再运行提交命令 git commit, 或者 git commit -a -m "***" * git rm * 文件未跟踪, 直接rm * 文件已跟踪, 先rm README 后 git status 提示 Changes not staged for commit, 然后 git rm README, 直接 git rm 也可以 ``` git rm log/\*.log # 删除 log/ 目录下扩展名为 .log 的所有文件 git rm \*~ # 该命令为删除以 ~ 结尾的所有文件 ``` * 如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f **这样的数据不能被 Git 恢复。** * git rm --cached README 想把文件从 Git 仓库中删除, 同时想让文件保留在磁盘,但是并不想让 Git 继续跟踪, 把本地缓存删除(改变成未track状态), 然后添加.gitignore * git mv 移动,改名 ``` git mv file_from file_to 相当于 $ mv README.md README $ git rm README.md $ git add README ``` * git log 提交历史 * git log -p -2 改动了哪里 * git log --stat -2 每次commit的统计消息 * git log --pretty=oneline ``` pretty的选项有(消息由简到繁) oneline short full fuller ``` * git log --pretty=format:"%h - %an, %ar : %s" 定制log, %h显示简短hash %s 提交说明, %an author , %ar 多久之前 * git log --pretty=format:"%h %s" --graph log提交合并分支图谱 * git log --since=2.weeks 两周内提交的 * git log -Sfunction_name -S 仅显示添加或移除了某个关键字的提交 示例: 2008 年 10 月期间,Junio Hamano 提交的但未合并的测试文件,可以用下面的查询命令: ``` $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \ --before="2008-11-01" --no-merges -- t/ ```
-
-
撤销操作
-
补充提交
git commit --amend 这个命令会将暂存区中的文件提交, 最终log只会有一次提交$ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend
-
取消暂存, 然后给以用 git checkout 来修改
git reset HEAD CONTRIBUTING.md
-
* 取消修改(未暂存, 否则先取消暂存, 丢弃工作区的修改)
git checkout -- CONTRIBUTING.md
-
远程仓库
添加远程仓库
-
修改 .git/config
git pull pb master
git push pb master # 本地的master分支推到pb远程仓库的master分支, 这里完整的其实应该是 master:master -
git remote add pb git://github.com/paulboone/ticgit.git
和修改 config [remote pb]效果一样git remote -v git fetch pb git remote show origin git remote rename pb paul git remote rm paul
-
-
打标签
Git 可以给历史中的某一个提交打上标签,以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点(v1.0 等等
-
列出标签
- git tag
- git tag -l 'v1.8.5*'
-
创建标签
Git 使用两种主要类型的标签:轻量标签(lightweight)与附注标签(annotated)。-
附注标签是存储在 Git 数据库中的一个完整对象。 它们是可以被校验的
- git tag -a v1.4 -m 'my version 1.4'
- git show v1.4
-
轻量标签本质上是将提交校验和存储到一个文件中 - 没有保存任何其他信息。 创建轻量标签,不需要使用 -a、-s 或 -m 选项,只需要提供标签名字:
- git tag v1.4-lw
- git show v1.4-lw
-
后期打标签
- git log --pretty=oneline
- git tag -a v1.2 9fceb02
-
共享标签
默认情况下,git push 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。 这个过程就像共享远程分支一样 - 你可以运行 git push origin [tagname]。- git push origin v1.5
- git push origin --tags
-
检出标签
在特定标签版本上创建分支- git checkout -b version2 v2.0.0
-
-
-
git 别名
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 config --global alias.unstage 'reset HEAD --' $ git unstage fileA $ git reset HEAD -- fileA $ git config --global alias.last 'log -1 HEAD' $ git last
-
git 回滚
回退命令:
$ git reset --hard HEAD^ 回退到上个版本
$ git reset --hard HEAD~3 回退到前3次提交之前,以此类推,回退到n次提交之前
$ git reset --hard commit_id 退到/进到 指定commit的sha码
强推到远程:
$ git push origin HEAD --force
git分支:
https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%80%E4%BB%8B
-
基础
- git branch testing 创建分支 ,分支名也是一个指针名,现在和master指向同一个 SnapShot
HEAD是一个指针,指向当前所在的本地分支(译注:将 HEAD 想象为当前分支的别名)。 在本例中,你仍然在 master 分支上。 因为 git branch 命令仅仅 创建 一个新分支,并不会自动切换到新分支中去
-
git log --oneline --decorate 用 git log 命令查看各个分支当前所指的对象。 提供这一功能的参数是 --decorate。
-
git checkout testing 切换HEAD指针到testing分支
-
git checkout master
-
git log --oneline --decorate --graph --all 输出你的提交历史、各个分支的指向以及项目的分支分叉情况
-
分支的新建与合并
带 -b 创建同时切换iss53 解决bug issure- git checkout -b iss53
** 请牢记:当你切换分支的时候,Git 会重置你的工作目录,使其看起来像回到了你在那个分支上最后一次提交的样子。 Git 会自动添加、删除、修改文件以确保此时你的工作目录和这个分支最后一次提交时的样子一模一样。**
中间hotfix紧急任务-
git checkout -b hotfix 紧急问题
修复hotfix -
git checkout master 切回master, 合并
-
git merge hotfix
-
git branch -d hotfix 删除 hotfix 分支, 此时 master和hotfix指向同一个快照
切回iss53, 继续处理 -
git checkout iss53
将master的改动同步到iss53 -
git merge master
修改完 iss53, 切回master -
git checkout master
合并iss53 到 master 注意此时由于三方合并, 会新建一个快照 -
git merge iss53
删除 iss53 -
git branch -d iss53
-
解决冲突
如果你在两个不同的分支中,对同一个文件的同一个部分进行了不同的修改,Git 就没法干净的合并它们。 如果你对 #53 问题的修改和有关 hotfix 的修改都涉及到同一个文件的同一处,在合并它们的时候就会产生合并冲突:
git status 查看冲突, 并修改iss53分支, 解决冲突, 再检出到master 来merge
- 管理分支
- git branch -v 查看每一个分支的最后一次提交
- git branch --merged 被合并的分支
- git branch --no-merged 没有被合并的分支
** 如果要删除一个未被合并的分支, -d 会报错, 可以使用 -D强删 **
-
分支开发流
- 长期分支 develop 或者 next 的平行分支,被用来做后续开发或者测试稳定性, 一些大型项目还有一个 proposed(建议) 或 pu: proposed updates(建议更新)分支,它可能因包含一些不成熟的内容而不能进入 next 或者 master 分支
- 特性分支 iss53 和 hotfix 分支
-
远程分支
远程引用是对远程仓库的引用(指针),包括分支、标签等等- git ls-remote 显式地获得远程引用的完整列表
并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢? master分支是主分支,因此要时刻与远程同步; dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步; bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug; feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
理清一下git的远程仓库交互:
(remote)/(branch) 形式命名
1, 添加远程仓库:
git remote add pb ****
2, 拉取远程分支
当克隆一个仓库时,它通常会自动地创建一个跟踪 origin/master 的 master 分支。 然而,如果你愿意的话可以设置其他的跟踪分支 - 其他远程仓库上的跟踪分支,或者不跟踪 master 分支
git checkout -b serverfix origin/serverfix # 创建并拉取origin的本地分支
git checkout --track origin/serverfix # 同上一条
git branch -u origin/serverfix # 随时设置本地当前分支跟踪的上游分支
Branch serverfix set up to track remote branch serverfix from origin.
git branch -vv # 查看本地分支和上游分支的对应关系
需要重点注意的一点是这些数字的值来自于你从每个服务器上最后一次抓取的数据。 这个命令并没有连接服务器,它只会告诉你关于本地缓存的服务器数据。 如果想要统计最新的领先与落后数字,需要在运行此命令前抓取所有的远程仓库。 可以像这样做:$ git fetch --all; git branch -vv
git pull 都会查找当前分支所跟踪的服务器与分支,从服务器上抓取数据然后尝试合并入那个远程分支。
git push origin --delete serverfix # 删除远程分支
- 堆栈保存工作区, 修改了一个branch, 但是不想commit, 需要切换到另外一个branch, 可以先暂存工作区
- git stash
- git stash list
- git stash pop
- git stash apply stash@{0}
- git reset --soft origin/master目标是更新本地分支和远程master分支同步(但是不会丢失本地更改),然后重新git add. git commit .git push.
网友评论