Git使用总结

排版凌乱,即用即补,一些常用的问题操作都汇总到这里了。

英文文档
https://git-scm.com/docs/
https://www.atlassian.com/git/tutorials/


fork后代码如何更新:

1.添加一个远程仓库到upstream
git remote add upstream git://github.com/原仓库地址

2.pull最新代码到当前fork的master分支
git pull upstream master

查看当前版本号信息

git rev-parse HEAD
97312e82fa9c7f419d5b42175f54d599130dd4a6

查看远程仓库地址

$ git remote -v

# 查看两次log记录基本修改
git diff --stat xxx xxx

# 查看两次log记录文件名及状态改变
git diff --name-status xxx xxx

# 查看两次log记录文件名
git diff --name-only xxx xxx

状态有几种:

' ' = unmodified
M = modified
A = added
D = deleted
R = renamed
C = copied
U = updated but unmerged

git拉错其他分支后恢复办法

git reset --hard ORIG_HEAD 

But you decided that the topic branch is not ready for public consumption yet.
"pull" or "merge" always leaves the original tip of the current branch in ORIG_HEAD, so resetting hard to it brings your index file and the working tree back to that state, and resets the tip of the branch to that commit.


git仓库嵌套仓库,即git子模块(git submodule)

# 添加子模块
git submodule add <repository> <path>

# 正常提交 
git add .
git ci -m ""

# clone拉取仓库,子模块内容无法获取,需要执行以下命令
git submodule init 初始化子模块
git submodule update 更新子模块
或者第一次下载主仓库时候,通过带参数直接下载到子模块
git clone 主仓库地址 --recursive

# 如首次clone主仓库没使用`recursive`,更新子模块需要使用:
git submodule update --remote
git submodule update

# 项目正常后,更新每个仓库
git submodule foreach git pull origin master
git submodule update --remote

# 删除子模块(通过git删除子模块路径,会直接修改.gitmodules, 无需手动清理)
git rm 子模块路径

# 遇到No submodule mapping found in .gitmodule for a path that's not a submodule错误,尝试通过以下方式解决
$ git submodule update --init 列出有问题的目录
$ git rm --cached OtherLibrary/MKStore 删除问题目录缓存

# 类似问题Git submodule add: “a git directory is found locally” issue
# 需要多个步骤删除

1. 删除`.gitmodules`文件中对应冗余配置
2. 删除` .git/config`文件中对应的冗余配置
3. 删除`.git/modules`下的冗余文件rm -rf .git/modules/path_to_submodule
4. 最终可以:git submodule add https://github.com/path_to_submodule



# bug:经常git status出现子模块git new commit
解决方案待确认:
[Git: can I suppress listing of 'modified content'/dirty submodule entries in status, diff, etc?](https://stackoverflow.com/questions/3240881/git-can-i-suppress-listing-of-modified-content-dirty-submodule-entries-in-sta)
[Ignore new commits for git submodule](https://stackoverflow.com/questions/14418352/ignore-new-commits-for-git-submodule/43440263#43440263)

* submodule配置ignore = all
* git status --ignore-submodules=dirty
* git config submodule.<name>.active false

子模块注意事项:

当我们运行 git submodule update 从子模块仓库中抓取修改时,Git 将会获得这些改动并更新子目录中的文件,但是会将子仓库留在一个称作 “游离的 HEAD” 的状态。 这意味着没有本地工作分支(例如 “master”)跟踪改动。 所以你做的任何改动都不会被跟踪。Git 工具 - 子模块


Git仓库压缩

git reflog expire --all --expire=now
git gc --prune=now --aggressive

显示单一文件修改记录

git log -p test.html

彻底删除文件,github根据不同情况给出不同方法:


查看commit修改内容

git show #CommitID

git如何删除本地所有未提交的更改
git 有什么命令可以清除工作区的文件


git处理冲突
Resolving a merge conflict from the command line

以github官方提供例子:冲突部分在<<<>>>之间

  • <<<之后,===之前,为目前分支内容
  • ===之后,>>>之前,为待合并分支内容 接下来就是处理<<<>>>之间需要保留的内容,执行git add -A保存,之后提交即可。 the number of planets are <<<<<<< HEAD nine ======= eight >>>>>>> branch-a

Git提交到多个远程仓库
github-help

git remote add origin https://github.com/*user*/*repo*.git

//提交多个仓库
git push --all

pull request流程
链接这里

git rp流程-知乎


单一文件回退到某个版本:
Reset or revert a specific file to a specific revision using Git?

# Assuming the commit you want is abcde
git checkout abcde file/to/restore

强制远程分支覆盖本地分支
How to force “git pull” to overwrite local files?

git fetch --all
git reset --hard origin/master
git reset --hard origin/your_branch

git标签

# git列表
git tag

# 打标签
git tag v0.1.1

# 补打标签
git tag v0.1.1 6224937

# 创建轻量标签-轻量标签是指向提交对象的引用(暂时没用到)
git tag v0.1.2-light

# 附注标签则是仓库中的一个独立对象。建议使用附注标签
git tag -a v0.1.2 -m "0.1.2版本备注"

# 给指定的commit打标签(即补打标签)
git tag -a v0.1.1 9fbc3d0

# 切换标签
git checkou [tagname]

# 删除标签
git tag -d v0.1.2

# 删除远程标签(需要先删除本地标签)
git push origin :refs/tags/v0.9

# 标签发布
git push origin v0.1.2 // 提交单一标签
git push origin --tags //提交所有标签

# 查看标签内容
git show v1.2.5

删除所有tags
remove all tag

# Delete local tags.
git tag -l | xargs git tag -d
# Fetch remote tags.
git fetch
# Delete remote tags.
git tag -l | xargs -n 1 git push --delete origin
# Delete local tasg.
git tag -l | xargs git tag -d

强行替换某一分支内容
git@Osc当中怎么把一个分支的内容完全替换成另一个分支的内容呢?

怎么说呢……[@Zoker](http://my.oschina.net/silentboy) 的答案确实能解决你的问题,但是你本地的master分支还是旧的,通常来说应该在本地做好修改再去push到远端,所以我推荐如下操作
git checkout master
git reset --hard develop  //先将本地的master分支重置成develop
git push origin master --force //再推送到远程仓库

强行覆盖远程分支方法

git push origin master --force

git回滚远程版本后强制提交

git push -f

安全方法见Git回滚远程版本

中文阮一峰
Git远程操作详解

本地仓库名与远程分支名字不同,如何提交
办法How can I push a local Git branch to a remote with a different name easily?
如不设置,每次提交需要按照以下方式

// 本地:远程
git push origin HEAD:liuyk-2016-7-27

git 2.0 默认git push为simple
Warning: push.default is unset; its implicit value is changing in Git 2.0
Git 2.0 更改 push default 为‘simple’

stream:‘matching’ 参数是 Git 1.x 的默认行为,其意是如果你执行 git push 但没有指定分支,它将 push 所有你本地的分支到远程仓库中对应匹配的分支。

simple:而 Git 2.x 默认的是 simple,意味着执行 git push 没有指定分支时,只有当前分支会被 push 到你使用 git pull 获取的代码。

stream:只关联git pull本分支获取的代码,此处是解决办法

查看所有别名

git config -l

查看所有的alias:List Git aliases

$ git config --get-regexp alias

取消工作区修改

git checkout -- .

修改远程仓库地址
修改仓库名后,是否需要更改clone地址。
官方给出的是可以不用换,但是还是强烈建议替换地址
Renaming a repository

In addition to redirecting web traffic, all git clone, git fetch, or git push operations targeting the previous location will continue to function as if made on the new location. However, to reduce confusion, we strongly recommend updating any existing local clones to point to the new repository URL. You can do this by using git remote on the command line:

git remote set-url origin *new_url*

查看分支关联

git branch -vv

本地新建分支与远程分支关联

git checkout -b release origin/release

fetch,merge

git fetch //默认获取所有分支最新
git fetch origin master // 拉取远程origin master分支最新
git log -p master..origin/master // 比较不同
git merge origin/master// 合并

查看单个文件修改记录

git log --patch -- [filename] //每次修改的内容
// 以上简写为
git log -p [filename]
git log -- [filename] //修改历史

显示哪些文件被改动

git log --name-status//仅显示哪些文件被改动

恢复单个文件到某个记录节点

git checkout <commit> <file>//会将文件存入缓存区
git commit -m "~~~~"

git初始化设置,个人信息

git config --global user.name "your_username"
git config --global user.email "your_email@domain.com"

初始化本地仓库

git init

加载文件至临时缓存

git add . //加载所有文件
git add my_file, my_other_file //加载制定文件夹

取消缓存

git reset

撤销

git checkout -- filename撤销提交 //撤销工作区file文件的修改,或者误删也可以找回
git checkout filename //测试也可撤销文件在工作区的修改
git reset HEAD readme.txt //撤销暂存区readme.txt
git reset //撤销暂存区的修改

撤销工作区untrack文件

git clean -f  [options: filename] //直接撤销untrack文件
git clean -nf //撤销前查看提示
git clean -f xx.txt //删除xx.txt文件

git clean -fd //连同文件夹一块撤销删除
git clean -nfd//撤销前查看提示

删除文件(不好用,删除)

git rm file

创建切换分支

git checkout -b new_feature // 创建切换分支
git branch new_feature  //创建分支
git checkout new_feature //切换分支

git checkout -b local_branch origin/remote_branch //用法舒服

参考链接Clone all remote branches with Git?

合并分支,切换到最终的分支,然后执行

git merge new_feature //合并原new_feature上的内容

删除分支

git branch -d new_feature

查看不同

$ git diff --name-status master分支..branchName其他分支 //查看分支不同
$ [Git](http://lib.csdn.net/base/28) diff 工作区与提交任务(提交暂存区,stage)中相比的差异
$ git diff HEAD 工作区和HEAD(当前工作分支)相比的差异
$ git diff --cached (或--staged)提交暂存区(提交任务,stage)和版本库中文件的差异

参考链接Showing which files have changed between two revisions
Git学习笔记(三) Git暂存区

回滚

git log //查看提交记录
git log --pretty=oneline //one line to show log
git checkout 085bbxx //回滚

推送到远程

git remote add origin https://your_username@bitbucket.org/your_username/name_of_remote_repository.git //第一次
git push origin master

别名

git config --global alias.c 'commit -m'
git config --global alias.c 'commit -m'
git config --global alias.co 'checkout'
git config --global alias.cob 'checkout -b'
git config --global alias.br 'branch'
git config --global alias.m 'merge'
git config --global alias.a 'add .'
git config --global alias.s 'status'
git config --global alias.dbr 'branch -d'

实质上,通过--global配置的,均在主目录下有一个.gitconfig配置文件,可以通过修改来更改删除查看alias
参考链接配置别名

其他方法
1) 创建一个文件 ~/.gitconfig
2)在文件中写入如下
[alias]
st = status
ci = commit
co = checkout
br = branch
unstage = reset HEAD --
last = log -1 HEAD
参考链接 git alias 设置

版本回退(mac操作错误)
在Git中,用HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^
回退到上一个版本

git reset --hard HEAD^

穿梭到某个版本

git reset --hard VersionID

查看之前纪录

git reflog

删除分支

git branch -d [branch-name]

不同

#  显示暂存区和工作区的差异
$ git diff
# 显示暂存区和上一个commit的差异
$ git diff --cached [file]

增加一个新的远程仓库(本地操作远程)

# 增加一个新的远程仓库,并命名
$ git remote add [shortname] [url]

远程仓库改名

git remote rename <原主机名> <新主机名>

查找.ssh文件

/Users/liwei/.ssh

生成.ssh

$ ssh-keygen -t rsa -C "youremail@example.com"

本地连接远程空仓库

$ git remote add origin git@github.com:michaelliao/learngit.git //关联
$ git push -u origin master //我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。

查看远程库的信息

$ git remote

新建远程分支

#方法:直接提交到新分支
git push origin '新分支名'
#完整的命令应如下:
git push origin '本地分支名':'远程分支名'

#本地与远程关联,这样以后直接输入git push即可
git push origin '远程分支名'

参考链接How do you create a remote Git branch?

有关远程分支关联疑问

git branch --set-upstream my_branch origin/my_branch

链接Why do I need to do --set-upstream all the time?

删除远程分支

git push origin :dev //删除远程dev分支

常用操作

git代码库回滚-删除远程仓库分支

远程分支
git checkout -b [分支名] [远程名]/[分支名]。如果你有 1.6.2 以上版本的 Git,还可以用 --track
选项简化:
$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.Switched to a new branch 'serverfix'

要为本地分支设定不同于远程分支的名字,只需在第一个版本的命令里换个名字:

$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.Switched to a new branch 'sf'

git协作流程
Git 协作流程

github release
release

目前还不清楚的问题:
git rest与git checkout log区别
git diff更多使用说明
git pull 和git fetch区别,如何一次获得所有仓库的更新并合并

参考链接
15 分钟学会使用 Git 和远程代码库
Book
廖雪峰
常用 Git 命令清单
git命令大全

@2017-06-23 14:35