常用git命令

常规操作

1. 远程主机操作

// 查看该主机的详细信息
$ git remote show <主机名>
// 添加远程主机,添加后通过《 8.取回远程主机某个分支的更新》来建立本地新的分支
$ git remote add <主机名> <网址>
// 删除远程主机
$ git remote rm <主机名>
远程主机的改名
$ git remote rename <原主机名> <新主机名>

2.checkout 远端指定分支

$ git checkout -b xxxx<本地分支名称> yyyy<远端分支名>

3.合并多个commit

$ git rebase -i HEAD~n  
// 将commit的前n个合并,在出现的窗口中将要合并的pick修改为squash
$ git push -f

4.清理远端已经删除的本地分支

$ git pull -p
// 等同于下面的命令
$ git fetch --prune origin 
$ git fetch -p

5.删除远端分支

$ git push origin :xxx
// 等同于
$ git push origin --delete xxx

6.清理本地没有的tag

// 先清理本地所有tag再获取远端的tag
$ git tag -l | xargs git tag -d
$ git fetch -t -p -f

7.推送到远端

$ git push <远程主机名> <本地分支名>:<远程分支名>
// 将本地分支推送到远端特定分支时出错先使用merge命令将远程分支合并到本地并解决冲突后提交, 然后再使用push命令
$ git merge <远程主机名>/<远程分支名>

8.取回远程主机某个分支的更新

git pull <远程主机名> <远程分支名>:<本地分支名>

9.撤销commit,但未git push的命令

// 完成撤销,同时将代码恢复到前一commit_id 对应的版本
$ git reset --hard id 
// 完成Commit命令的撤销,但是不对代码修改进行撤销,可以直接通过git commit 重新提交对本地代码的修改
$ git reset id 
// 撤销当前的所有修改
$ git reset --hard HEAD

10. master 回退服务端到特定版本

// checkout 要回退的当前最新版(如源名是upstream)
$ git checkout -b upstream_master upstream/master
// 回退到2295c189c22b960e2852f5b0495c7173b404b270 
$ git reset --hard 2295c189c22b960e2852f5b0495c7173b404b270
// 强制推送当前版本到主干
$ git push upstream HEAD:master

11.比较两个版本间的差异

$ git diff commit_id_old commit_id_new

12.更改远端分支

// 先删除老的分支
$ git push --delete origin old_branch
// 修改本地的分支名
$ git branch -m old_branch new_branch
// 推送本地的新分支到远端
$ git push origin new_branch:new_branch

13.生成patch

// 生成从commitid为xxx到当前提交的patch,每个提交一个patch文件, 存放在当前的dir目录下
$ git format-patch xxx -o dir

14.应用patch

// 先检测xxx.patch文件是否和当前的版本有冲突
$ git apply --check xxx.patch
// 再将xxx.patch合并到当前的分支中
$ git apply xxx.patch

15.修改源地址

$ git remove set-url origin newaddr

16.合并某个commit到当前aa分支上

// 其中commit_id是某个非aa分支上的commit_id
$ git checkout aa
$ git cherry-pick commit_id

17. 修改分支名

$ git  branch -m old_branch new_branch

18. 合并分支多个commit到主分支,使主分支只有有一个干净清晰的log

$ git checkout master //切换回主分支
$ git pull origin master //拉取远端master代码
$ git merge --squash 分支名  //如遇冲突就解决冲突
$ git commit -m "这里是注释"
$ git push origin master //提交master代码到远端

19.git submodule 添加子仓库

Git Submodule 允许一个git仓库,作为另一个git仓库的子目录,并且保持父项目和子项目相互独立

// 查看子模块
git submodule
// 为当前工程添加指定分支 xx 的 submodule
git submodule add -b xx <仓库地址> <本地路径>
// 为当前工程添加submodule
git submodule add <仓库地址> <本地路径>
// 下载的工程带有submodule,使用以下命令下载子模块内容
git submodule update --init --recursive
// 更新子模块为远程项目的最新版本
git submodule update --remote
// 删除子模块需要经过以下4步, 以删除assets文件夹为例
    // 1. 删除子模块文件夹
    git rm --cached assets
    // 2. 删除.gitmodules文件中相关子模块信息
    // 3. 删除.git/config中的相关子模块信息
    // 4. 删除.git/modules/src/文件夹中的相关子模块文件

20 更新源地址

$ git remote set-url origin <new_addr>

21 创建空白分支

利用git checkout的 --orphan参数来建立一个没有任何历史记录的空分支
// 1. 建立命令为空分支
git checkout --orphan test_empty
// 2. 删除所有文件, 注意后面的.
git rm -rf .
// 3. 添加新的文件, 未添加新的文件则分支 test_empty 不可见
git add xxx
git ci -a "add xxx file"
// 4. 推送到远端
git push --set-upstream origin test_empty

22 查看当前配置信息

// 查看全局配置信息
git config --system --list
// 查看当前用户的global全局配置
git config --global --list
// 查看当前仓库配置信息
git config --local --list

二. tag 操作

1. 显示本地 tag

git tag

2. 删除本地tag

// 删除名为tag_name的一个标签
git tag -d tag_name
// 删除本地所有标签
git tag -d $(git tag -l)

3. 删除远端某个tag

// 删除远端名为release-3.0.0-13的tag
git push origin :refs/tags/release-3.0.0-13
// 删除远端所有的标签
git push origin --delete $(git tag -l)

4.批量删除远端tag

//删除远端所有以release-开头的tag
git show-ref --tag | awk '/release-/ {print ":" $2}' |xargs git push origin

5. 批量删除本地分支

// 删除以release-开头的本地tag
git tag -l | awk '/release-/' |  xargs git tag -d

6.添加标签

// 添加一个名为xxx的标签
$git tag -a xxx -m"xxxxxxx"
// 将标签推送到服务器
$git push origin tag-names

三. 遇到问题及解决方法

1. git push 或者 clone 出错

出错代码:

1
2
3
4
error: RPC failed; curl 56 OpenSSL SSL_read: error:1408F119:SSL routines:ssl3_get_record:decryption failed or bad record mac, errno 0
fatal: the remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

解决方法:增大 postbuffer

1
git config --global http.postBuffer 1048576000

2. git archive 时没有同步submodule

在使用 git archive的时候,发现并没有把项目里的submodule里的文件归档过去,只有一个submodule的文件夹

解决思路:1、先在父目录使用git archive后,再通过git submodule foreach遍历submodule,对sudmodule里的文件进行git archive,这样最后,所有文件都能归档到一个地方了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 函数第一个参数为项目名
function pack() {
PKG_NAME=${1}
PKG_VERSION=$(grep '^Version:' ${PKG_NAME}.spec | awk '{print $2}')
cd ..
curDir=`pwd`
PROJECT_NAME="${PKG_NAME}-${PKG_VERSION}"
git archive --format=tar --prefix=$PROJECT_NAME/ HEAD | (tar xpf -) #归档父项目后解压到指定目录
git submodule foreach | while read subdir; do
subdir=${subdir#*\'}; #去除最左边的单引号
subdir=${subdir%*\'}; #去除最右边的单引号
[ "${subdir}" = "" ] && continue; #加一步判断,subdir为""则continue
echo Running git archive submodules... ${subdir}
(cd ${subdir} && git archive --format=tar --prefix=${subdir}/ HEAD | (cd ${curDir}/${PROJECT_NAME}/ && tar xpf -)); #归档submodule后解压到父目录
done

tar zcpf ${PROJECT_NAME}.tar.gz ${PROJECT_NAME}
/bin/mv -f ${PROJECT_NAME}.tar.gz packaging
rm -rf ${PKG_NAME}-${PKG_VERSION}
cd -
}

3. git status 中文显示乱码

原因:

在默认设置下,中文文件名在工作区状态输出,中文名不能正确显示,而是显示为八进制的字符编码。

解决办法:

将git配置文件 core.quotepath项设置为false。quotepath表示引用路径,加上–global表示全局配置

git bash终端输入命令:

1
git config --global core.quotepath false

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!