Git 基本操作

Git 是目前世界上最先进的分布式版本控制系统(廖雪峰说的),2008 年,GitHub 网站上线,它为开源项目免费提供 Git 存储,无数开源项目开始迁移至 GitHub。与集中式的版本控制 SVN 不同,分布式版本控制系统没有“中央服务器”,每个人的电脑上都是一个完整的版本库。

本文记录 Git 的各种常用的基本操作,方便使用时查阅。如果你是头一次接触 Git,建议先找一份教程完整的看一看,推荐 廖雪峰的 Git 教程,虽然有些内容讲的也比较绕,但是入门来说应该足够了。

初始设置

配置用户名和 Email

git config --global user.name "Your Name"
git config --global user.email "email@example.com"

在本地 Git 配置后,还需要在 GitHub 账号的 Settings - Emails 中添加并验证这个邮箱,才能与自己的 GitHub 账号关联。

设置和取消代理

设置合适的科研网络环境可以有效解决克隆仓库时速度慢的问题。

# http
git config --global https.proxy http://127.0.0.1:8080
git config --global http.proxy https://127.0.0.1:8080

# socks5
git config --global https.proxy socks5://127.0.0.1:1080
git config --global http.proxy socks5://127.0.0.1:1080

git config --global unset http.proxy
git config --global unset https.proxy

基本操作

在本地创建版本库(repository)

git init <directory>
# 或者:
cd <directory>
git init

这样, <directory> 目录就变成了 Git 可管理的仓库,可以发现目录下多了一个隐藏的 .git 目录,不要手动改动这个目录里的东西。

查看仓库状态

如果第一次接触 Git,建议先搞清楚工作区(Working Directory)、版本库(Repository)和暂存区(Stage)的概念,可参考 廖雪峰的教程

git status

使用这个命令可以看到:

  • 工作区中已被修改但是未被添加到暂存区的文件(Changes not staged for commit)
  • 已添加到工作区但是未提交的文件(Changes to be committed)
  • 尚未被 Git 追踪的文件(Untracked files)

暂存区相关操作

git add xxx.txt             # 将工作区中修改的文件(Changes not staged for commit)添加到暂存区
git rm --cached xxx.txt # 将暂存区的文件撤回到工作区
git restore xxx.txt # 丢弃工作区中对文件的修改,使用暂存区中的版本

要注意区分第二个和第三个命令,它们的作用是不一样的。如果记不清这几个命令,输入 git status 会得到提示,提示中对命令的解释也很明确。

本地版本库操作

git commit -m "blablabla..."    # 将暂存区中的文件提交到版本库。需提供版本说明信息
# 执行这个命令前需要先把要提交的东西使用 git add 命令添加到暂存区
# 然后可以使用 git status 确认一下要提交的内容

git log [--oneline] # 查看版本库的所有 commit 记录。添加 --oneline 参数可以在一行显式

git reflog # 查看命令历史,可以看到所有之前使用过的命令记录

默认的 log 命令显示的内容比较长,每次写都带参数的话又比较麻烦,我们可以使用 Git 的别名功能。将下面的这条命令输入到命令行中:

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

之后我们就可以用 git lg 来替代 git log ,可以看到,这样不仅显示的内容更加清晰,还能够显示出 commit 树的分支情况。

远程仓库操作

git clone git@github.com:ChinaNuke/learnGit.git                 # 克隆远程仓库

git remote add origin git@github.com:ChinaNuke/learnGit.git # 添加远程仓库

这两条命令的主要区别是,克隆一般用于 GitHub 上已经有了在开发的项目,我们需要把整个项目仓库下载到本地的情况(先有远程库,后有本地库);而添加用于刚创建 GitHub 仓库,里面并没有东西的情况(先有本地库,后有远程库),但也可以用于第一种情况。

git push -u origin master       # 把本地库的所有内容推送到远程库上,并为 master 分支建立链接
# origin 是远程库的名字,可以改成其他的,但一般用 origin 比较直观
# 一般来说,仅第一次推送时需要建立链接,后续推送不需要

git push # 把当前分支的内容推送到远程库对应的分支

git pull # 从远程库拉取分支的内容

git reset --hard HEAD^ # 回退到上一个版本。HEAD^^ 为上上个版本,以此类推
git reset --hard 1094a # 回退 / 还原到提交编号开头为 1094a 的版本

分支管理

留坑。

多人协作项目一般流程

使用 Git 和 GitHub 可以很方便地进行多人协作。多人协作中所用到的大部分命令已在前面提到,此处不对命令进行详细解释。

对于已经在 GitHub 上建好的项目,我们要先把它克隆到本地。

git clone git@github.com:ChinaNuke/learnGit.git [local directory]

其中,参数中的链接是远程仓库的地址,可以在 GitHub 项目页面找到。 [local directory] 为可选参数,如果指定了目录名,则克隆到这个目录,未指定则默认以仓库名来命名目录,此处为 learnGit

之后我们需要 cd learnGit 进入到仓库目录中,后续的操作都在仓库中进行。我们可以使用 git remote -v 命令查看当前仓库本地链接到的远程仓库,一般会看到 fetchpush 两个地址,如果没有推送权限,就看不到 push 地址。

然后我们就可以在本地进行开发了,开发过程中我们可以随时使用 git add 命令将工作区中修改过的文件添加到暂存区,然后使用 git commit 命令进行提交,使用 git lg 命令可以查看 commit 树。

在多人开发中,很有可能遇到这样一种情况:我在本地进行开发,其他人也在他的本地基于同一个版本进行开发,然后他在我们之前将修改提交到了远程仓库,这时候我们 push 时就会被拒绝。

To github.com:github.com:ChinaNuke/learnGit.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to 'git@github.com:ChinaNuke/learnGit.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

原因显而易见,那如何解决呢?我们先用 git pull 命令把最新的提交从远程库拉取下来,在本地合并,这时可能会有冲突,需要我们手动进行合并(冲突合并方法见廖雪峰教程)。合并完冲突之后就可以再次进行推送了,但是在这之前我们先使用 git lg 命令看看现在的 commit 树,它是不直的,类似这个样子:

* d1be385 (HEAD -> master, origin/master) init hello
* e5e69f1 Merge branch 'dev'
|\
| * 57c53ab (origin/dev, dev) fix env conflict
| |\
| | * 7a5e5dd add env
| * | 7bd91f1 add new env
| |/
* | 12a631b merged bug fix 101
|\ \
| * | 4c805e2 fix bug 101
|/ /
* | e1e9c68 merge with no-ff
|\ \
| |/
| * f52c633 add merge
|/
* cf810e4 conflict fixed

这样很不好看,对强迫症很不友好。我们可以在推送前再加一步 git rebase ,正常情况下 Git 会自动将 commit 树整理成直的,执行完之后我们可以再次使用 git lg 看一下。最后,我们就可以用 git push 推送提交了。

关于 commit 树要整理成直的还是保留原始的修改记录,网上众说纷纭,我更倾向于整理成直的,清晰又直观!

建议参考资料

Git Cheat Sheet: https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet

廖雪峰 Git 教程: https://www.liaoxuefeng.com/wiki/896043488029600

作者

ChinaNuke

发布于

2020-09-08

许可协议

评论