Tips for Git

Git名词

  • master: 默认开发分支
  • origin: 默认远程版本库
  • Index / Stage:暂存区
  • Workspace:工作区
  • Repository:仓库区(或本地仓库)
  • Remote:远程仓库

管理文件

丢弃未追踪文件

1
2
git clean -f   # 删除 untracked files
git clean -fd # 删除 untracked 文件和目录

在用上述git clean前,强烈建议==加上-n参数==来先看看会删掉哪些文件,防止重要文件被误删,即

1
2
git clean -nf
git clean -nfd

然后再执行删除命令。

丢弃工作区修改

丢弃针对工作区文件的修改,使文件恢复到未修改前的状态

1
2
git checkout -- <file> # restore <file>
git checkout . # restore all files, 不包括untracked files

丢弃暂存区修改

使用如下命令可以把暂存区的修改撤销掉(unstage file),重新放回工作区

1
2
3
git reset         # unstage all the files
git reset <file> # unstage file, 重置暂存区的指定文件,与上一次commit保持一致
git reset HEAD <file> # unstage <file> only

丢弃本次提交

如果git commit之后后悔了,可以通过下面命令撤销操作

1
2
3
git reset --soft HEAD^  # 撤销commit,仍然保留更改
git reset --mixed HEAD^ # 撤销commit、add,仍然保留更改
git reset --hard HEAD^ # 撤销commit、add,丢弃更改

如果git commit注释写错了,只是想改一下注释,只需要:

1
git commit --amend

此时会进入默认vim编辑器,修改注释完毕后保存就好了。

删除远程仓库文件夹

在更新本地.gitignore文件后,可能会忽略本地的某个文件夹,但此时该文件夹可能已经存在于远程仓库了,此时需要删除掉远程仓库中的对应文件夹

1
2
3
git rm -r --cached some-directory
git commit -m "Remove the now ignored directory some-directory"
git push origin master

版本回退

1
2
git reset --hard HEAD^        # 回退到上个版本
git reset --hard commit_id # 退到/进到指定commit_id

更新/合并代码

远程 -> 本地

克隆远程仓库到本地

1
2
git clone repo-url    # Clone the repository
git clone --recursive repo-url # Clone the repository with submodules

更新子模块:

1
2
git submodule update --init --recursive
git submodule update --recursive --remote

有时候clone的时候老是出现错误error: RPC failed; curl transfer closed with outstanding read data remaining或者错误remote end hung up unexpectedly,这可能是由于远程仓库太大,这时候可以先进行shallow clone,即只拷贝最后一次递交的代码,然后再更新整个git历史:

1
2
3
git clone http://github.com/large-repository --depth 1
cd large-repository
git fetch --unshallow # update the repository with its history.

合并远程分支到本地

1
2
3
4
(master)$ git fetch origin master:temp  # 从远程origin仓库的master分支下载到本地并新建一个分支temp
(master)$ git diff temp # 比较本地的仓库和远程仓库的区别
(master)$ git merge temp # 合并temp分支到master分支
(master)$ git branch -d temp # 如果不想要temp分支了,可以删除此分支

拉取远程分支到本地

拉取远程分支到本地,并在本地创建分支

1
2
git checkout -b temp1 origin/temp2 # 拉取远程temp1分支到本地创建temp2分支,并切换到temp2分支
git fetch origin temp1:temp2 # 拉取远程temp1分支到本地创建temp2分支

本地 -> 远程

推送本地分支到远程

1
(dev)$ git push origin dev:dev  # 推送本地dev分支到远程dev分支

本地仓库连接远程仓库

本地仓库首次连接远程仓库

1
2
3
4
5
6
cd existing_folder  # 进入本地仓库文件夹
git init # 初始化git,生成.git隐藏文件夹
git remote add origin https://github.com/user/repo.git # 连接远程仓库
git add .
git commit -m "Initial commit"
git push -u origin master # 推送本地到远程

克隆仓库并推送到自己仓库

首先克隆别人的仓库到本地

1
git clone https://github.com/other-account/other-repository.git

再在github.com创建自己的空仓库如your-account/your-repository

将本地仓库当前的origin重命名为upstream

1
git remote rename origin upstream

origin重新设置为指向自己的远程仓库

1
git remote add origin https://github.com/your-account/your-repository.git

将本地仓库推送到自己的远程仓库

1
git push origin master

现在,origin指向你自己的仓库,upstream指向别人的仓库,创建一个你自己的分支如git checkout -b my-feature-branch,你可以推送自己的更改到仓库,也可以通过命令git pull upstream master来拉取别人仓库的更改到你的master分支。

branch

常用命令

1
2
3
4
5
6
7
8
9
git branch        # 查看本地分支
git branch -r # 查看远程分支
git branch --all # 查看所有分支
git branch [name] # 创建本地分支
git checkout [name] # 切换到某分支
git checkout -b [name] # 创建新分支并立即切换到该分支
git branch -d [name] # 删除已有分支,-d选项只能删除已经参与了合并的分支,对于未有合并的分支是无法删除的。如果想强制删除一个分支,可以使用-D选项
git merge [name] # 合并分支,将名称为[name]的分支与当前分支合并
git push origin [name] # 创建远程分支(本地分支push到远程)

创建分支

在本地仓库创建分支

1
git checkout -b temp  # 新建并切换到temp分支

如果想在本地仓库新建一个空白分支

1
2
3
git checkout --orphan tmep  # 新建并切换到temp分支
# 但此时分支中的文件处于staged,未commit的状态,需要清空index
git reset --hard #

删除分支

1
2
3
git branch -d temp  # 删除本地temp分支
git branch -D temp # 强制删除本地temp分支
git push origin --delete temp # 删除远程temp分支

tag

1
2
3
4
5
6
git tag           # 查看版本
git tag [name] # 创建版本
git tag -d [name] # 删除版本
git tag -r # 查看远程版本
git push origin [name] # 创建远程版本(本地版本push到远程)
git push origin :refs/tags/[name] # 删除远程版本

gitignore

更新.gitignore文件

1
2
3
git rm -r --cached .
git add -A
git commit -m "update .gitignore"

submodule

添加/更新子模块

1
2
3
4
git submodule add [url] [path]
# 如git submodule add git://github.com/soberh/ui-libs.git src/main/webapp/ui-libs
git submodule init # 初始化子模块,只在首次检出仓库时运行一次就行
git submodule update #更新子模块,每次更新或切换分支后都需要运行一下

删除子模块

删除项目中的一个子模块分四步走:
1) git rm --cached [path]
2) 编辑“.gitmodules”文件,将子模块的相关配置节点删除掉
3) 编辑“.git/config”文件,将子模块的相关配置节点删除掉
4) 手动删除子模块残留的目录

其他命令

1
2
git status
git ls-files # 查看git追踪的文件

下载GitHub仓库的某个文件夹到本地

1
2
SUBDIR=foo
svn export https://github.com/google-research/google-research/trunk/$SUBDIR

GitHub 提交Pull Request

首先 folk 开源仓库到自己 GitHub 仓库,然后 clone 自己的仓库到本地,更改并 commit,push 到自己的远程分支,在 GitHub 网页发起 Pull Request。

Ref: 如何给开源项目贡献代码

Key

  1. Generate Key

    1
    ssh-keygen -t rsa -C "your.email@example.com" -b 4096

    然后提示Enter file in which to save the key,输入文件名(包括文件路径),如Windows系统一般是/c/Users/your_user_name/.ssh/id_rsa,按回车,提示Enter passphrase (empty for no passphrase):,直接回车,提示Enter same passphrase again:,再按回车,完成。

  2. Add key
    用文本编辑器打开/c/Users/your_user_name/.ssh/id_rsa,全选复制,再打开Gitlab网页端,点击右上角Setting, 点击左侧SSH Keys,粘贴, 点击Add Key,完成。

Ref