Git 使用经验
Git 是个很实用的版本控制工具,教程网上有许多,这里就不重复了。
下面列举一些我在使用 Git 的时候遇到的问题的解决方法。
第一次安装 git 要配置自己的邮箱和名字
git config --global user.name "Your Name"
git config --global user.email "email@example.com"
eg:
git config --global user.name "Yzr0512"
git config --global user.email "yzr20121216@gmail.com"
文章目录
1 创建版本库
git clone <url> # 克隆远程版本库
git init # 初始化本地版本库
1.1 如果我已经有了一个项目,怎么给他建立仓库
解决办法:
(1) 首先建议先添加 .gitignore 文件,该文件作用是告诉 git,哪些文件不需要跟踪,有一些文件,比如编译生成的程序,这些文件只要有源码就能再次编译生成,所以不需要跟踪,而且这些文件通常都很大,忽略他们还可以避免仓库占用空间过大。下面是一个 .gitignore 的例子。(更多的 gitignore 模板请见此 GitHub 项目https://github.com/github/gitignore)
.vscode/
__pycache__/
checkpoint/
data/
logs/
samples/
(2) 初始化仓库。在终端(命令行)中跳到项目所在的目录,输入命令
git init
初始化完成以后该目录内的文件就可以用 git 进行版本跟踪啦。
PS: 此时项目的文件夹会多出一个名为 .git
的隐藏文件夹。这个文件夹储存了你提交的各个版本的修改信息,很重要,勿删。
(3) 现在来进行第一次跟踪。在仓库中随意添加一些文件,比如 abc.txt
,然后在终端(命令行)中输入命令
git add .
.
表示所有文件,该命令的作用就是把所有修改过的文件都添加到暂存区,不含 .gitignore
中指定的文件。该命令正确运行的话应该是没有输出信息的。
若想要查看现在暂存的修改记录,可使用 git status
命令。可以看到添加的 abc.txt
文件已经被跟踪。
PS:add 的时候可能会遇到下面这个警告,可以无视。
warning: LF will be replaced by CRLF in utils.py.
The file will have its original line endings in your working directory
(4) 提交修改。在终端(命令行)中输入以下命令
git commit -m "commit message"
在 commit message 中可以备注本次修改的一些内容,方便后面查错。
(5) 与远程仓库连接。对于一些本是个人开发的项目,后期因某些原因变为多人协作,这时候仅依赖本地的 Git 仓库是不够的,还需要依赖线上的代码托管平台。这里就以 GitHub 为例,将本地的仓库与 GitHub 上的仓库连接。
这里事先已经创建好了一个远程仓库(此处链接为虚构的,仅做参考,实际请替换为自己的仓库链接):https://github.com/username/example.git
在终端(命令行)中输入以下命令,注意更换仓库链接。
git remote add origin https://github.com/username/example.git
然后再用 git remote -v
命令可以看到当前远程仓库的地址。
现在就可以和小伙伴一起协作开发程序啦!
首先进行第一次 pull,将远程仓库中的内容拉取到本地中。
$ git pull
由于我目前本地仓库是空的,没有任何分支,所以可以看到拉取完提示增加了一个新分支 master。
但此时使用 git branch
命令是看不到任何分支信息的,不知道是什么原因。
切换到分支 master 以后就可以看到增加了一个分支。
$ git checkout master
$ git branch
PS: 将本地的修改 push 到远程仓库之前需要先将远程仓库 pull 到本地。因为远程仓库是不会给你处理合并冲突的,所以你要先将远程仓库 pull 下来,把合并之后的冲突全部解决之后才能 push。
2 修改和提交
git status # 查看状态
git diff # 查看变更内容
git add . # 跟踪所有改动过的文件
git add <file> # 跟踪指定的文件
git mv <old> <new> # 文件改名
git rm <file> # 删除文件
git rm --cached <file> # 停止跟踪文件但不删除
git commit -m "commit message" # 提交所有更新过的文件
git commit --amend # 修改最后一次提交
2.1 已经跟踪的文件如何忽略?
已经跟踪的文件是不受 .gitignore 文件的影响的。
所以需要先把仓库中已跟踪的文件删除。
根据情况,如果需要保留本地文件的话就加上 --cached
参数。
# 仅删除readme1.txt的跟踪,保留在本地文件。
$ git rm --cached readme1.txt
# 删除readme1.txt的跟踪,并删除本地文件。
$ git rm readme1.txt
执行完毕后还需要 commit 一次才能完成删除。
3 查看提交历史
git log # 查看提交历史
git log -p <file> # 查看指定文件的提交历史
git blame <file> # 以列表方式查看指定文件的提交历史
4 撤销
git reset --hard HEAD # 撤销工作目录中所有未提交文件的修改内容
git checkout HEAD <file> # 撤销指定的未提交文件的修改内容
git revert <commit> # 撤销指定的提交
4.1 如何进行版本回滚
这个问题是 git 的核心,git 要解决的自动化管理多个版本的源代码,同时可以在这些版本之间自由切换,根据回滚的版本数不同,主要有以下几种情况:
情况1,将当前分支回滚到上个版本。
$ git reset --hard HEAD^
情况2,将当前分支回滚到三个版本之前。可以修改数字以回退到 n 个版本之前。
$ git reset --hard HEAD~3
情况3,不确定自己要回滚的版本是第几个,但知道是哪一次 commit。那么可以通过查看日志得到该 commit 的 SHA(log 输出的信息中 commit 后接的就是 SHA 码,这个码可以用来标识回滚的版本),然后跳到 SHA 码对应的版本。
$ git log
commit 94fc8c2fdd7cfe21789bc1d28a0c22cf17c33982 (HEAD -> dev, origin/dev)
Author: Benko <123456@qq.com>
Date: Sat Feb 8 21:22:20 2020 +0800
实现用户信息/密码/头像的修改功能
commit 4aa81791e074ba7bdeba590b952f27e03a854e9b
Author: Benko <123456@qq.com>
Date: Sat Feb 8 16:18:22 2020 +0800
完成user_info页基本信息展示,并实现了user_info页面打开时未登录检测及跳转至登录页面
commit 09669540f785c9d891f070b975376fe5c355e7bc
Author: Benko <123456@qq.com>
Date: Fri Feb 7 23:31:01 2020 +0800
完成user_info页面的制作
$ git reset --hard 096695
PS:SHA 码可以不打全,输入前几位即可。
4.2 如何回到未来的版本
回滚版本以后用命令 git log
是看不是当前版本以后的 commit 的,如果又想回去未来怎么办?解决方法如下:
使用下面命令找到未来版本 commit 的 SHA。这个命令可以看见命令的日志,每条日志的前面都会有个 commit 的标识,找到自己想要的那个 commit 前面对应的 SHA 码。
$ git reflog
得到 SHA 码以后参照4.1的情况3进行跳转。
$ git reset --hard commit_id
4.3 回滚指定文件
首先要找到要回滚的版本的 SHA 值。
$ git log main.js
利用 SHA 回滚特定文件。注意:这里为了方便操作,使用 SHA 的前六位就可以。
$ git checkout 2d1ed0 main.js
回滚后还需要提交一下。
$ git commit -m '回滚main.js'
5 分支相关
git branch # 显示所有分支
git branch <new branch> # 创建分支
git branch -d <branch> # 删除分支
git checkout <branch/tag> # 切换到指定的分支/标签
git tag # 列出所有本地标签
git tag <tagname> # 基于最新提交创建标签
git tag -d <tagname> # 删除标签
git merge <branch> # 合并指定分支到当前分支
git rebase <branch> # 衍合指定分支到当前分支
6 远程操作
git remote -v # 查看远程版本库信息
git remote show <remote> # 查看指定远程版本库信息
git remote add <remote> <url> # 添加远程版本库
git fetch <remote> # 从远程库获取代码
git pull <remote> <branch> # 下载代码及快速合并
git push <remote> <branch> # 上传代码及快速合并
git push <remote> :<branch/tag-name> # 删除远程分支或标签?
git push --tags # 上传所有标签
(此建议待考究)同步远程代码建议使用 git fetch
,而不是 git pull
。
git fetch
和 git pull
的区别请见:https://blog.csdn.net/weixin_41975655/article/details/82887273
大概的说一下,不保证准确性。
我们本地仓库中除了本地分支以外,实际上还有一个对应远程分支的克隆。
当我们执行 git pull
的时候,程序会从远程分支上下载变更内容并自动合并到本地分支中。
合并完成以后本地与远程分支的状态是一样的。
而我们执行 git fetch
的时候,程序会从远程分支上下载变更内容来更新远程分支在本地的克隆。
此时本地分支是没有变化的,还需要手动将远程分支在本地的克隆和本地分支合并。
两个命令的区别就在于这个合并操作上,至于为什么要推荐时候后者,还需要深入学习一下。
6.1 从远程分支拉取更新
从远程分支下载修改到本地对应的远程分支副本。
$ git fetch origin dev
将本地分支和本地的远程分支副本合并。
$ git fetch dev origin/dev
6.2 关联本地分支和远程分支
使用下面命令可以看到本地分支与远程分支之间的关联。
$ git branch -vv
可以看到 dev 和 master 在远程仓库 origin 中都有对应的分支,且已经关联。而 dev-dan 仅是一个本地分支,没有与任意一个远程分支关联,在此分支中无法执行 pull 和 push 命令。
使用下面两条命令中的其一来建立当前分支和远程分支的关联。
$ git branch -u origin/dev
# or
$ git branch --set-upstream-to origin/dev
若不慎误操作,可以通过下面这条命令来解除当前分支与远程分支的关联。
$ git branch --unset-upstream
6.3 从远程分支拉取一个本地不存在的分支
在本地创建一个分支,将该分支与远程分支关联,然后 pull。
参考6.2。
6.4 拉取所有远程分支
这个命令不接参数好像是会把远程库所有分支都下载下来,那么遇到大型库岂不是下很久?
$ git fetch
切换分支,但是我在切换的时候提示的信息感觉像是个错误,实际却没问题?
$ git checkout <branch>
在这个过程中我遇到个问题:
执行完第1步的时候我使用git branch
看了一下本地的分支,发现并没有增加新的branch。
然后执行第2步之后再用’git branch’看了下,这才出现新的branch,每个分支都需要这样做才会出现?
6.5 修改远程库的地址
三种方法:
方法1,直接修改。
$ git remote set-url origin [new-url]
方法2,先把原来的删除了再添加。
$ git remote rm origin
$ git remote add origin [new-url]
方法3,修改config文件。(没试过)
Tips
使用场景中经常需要返回某个版本的状态的话,应该创建多个分支。
比如,我做实验的时候有很多种想法,实验之前并不知道效果如何,效果不好的话要回滚,所以每次实验的时候就从主分支创建一个分支,实验完效果好就合并到主分支,不好就直接返回主分支。这样做还有个好处就是很方便地重现某次实验的内容,如果使用上面提到的回滚操作的话操作会麻烦。
多个分支可能会有一些是共有的东西,后面任意一条分支对这些内容修改(修bug、功能添加、改进等)以后要应用到所有分支是很麻烦的,那么应该单独用个分支用来存这些共有的内容,修改的时候就在这个分支上面去修改。