Git 学习笔记
大纲
原理
基本操作
分支管理
标签管理
忽略文件
别名
撤销Git操作
跳转
子模块
大小写
远程操作
clone
remote
fetch
pull
push
github
Git_LFS
原理
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的 gitcode 文件夹就是一个工作区.
版本库(Repository)
工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库.
Git 的版本库里存了很多东西,其中最重要的就是称为 stage(或者叫 index)的暂存区,还有 Git 为我们自动创建的第一个分支 master,以及指向 master 的一个指针叫 HEAD .
把文件往 Git 版本库里添加的时候,是分两步执行的:
第一步是用 git add 把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用 git commit 提交更改,实际上就是把暂存区的所有内容提交到当前分支.
因为我们创建 Git 版本库时,Git 自动为我们创建了唯一一个 master 分支,所以,现在,git commit 就是往 master 分支上提交更改.
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改.
.git 目录
结构展开类似
conf
conf 文件中包含着 repository 的配置,包括 remote 的地址,提交时的 email, username, 等等,所有通过 git config .. 来设置的内容都在这里保存着。如果熟悉甚至可以直接修改该文件。
description
被 gitweb(github 之前) 用来描述 repository 内容。
hooks
hooks,国内通常被翻译成钩子,git 中一个比较有趣的功能。可以编写一些脚本让 git 在各个阶段自动执行。这些脚本被称为 hooks, 脚本可以在 commit/rebase/pull 等等环节前后被执行。脚本的名字暗示了脚本被执行的时刻。一个比较常见的使用场景就是在 pre-push 阶段检查本地提交是否遵循了 remote 仓库的代码风格。
info exclude
该文件中定义的文件不会被 git 追踪,和 .gitignore 作用相同。大部分情况下 .gitignore 就足够了,但知道 info/exclude 文件的存在也是可以的。
object
每一次创建一些文件,提交,git 都会压缩并将其保存到自己的数据结构中。压缩的内容会拥有一个唯一的名字,一个 hash 值,该 hash 值会保存到 object 目录中。
HEAD
HEAD 可以比喻成一个指针,指向当前工作的分支。
基本操作
分支管理
标签管理
忽略文件
一个名为 .gitignore 的文件,列出要忽略的文件模式. 配置语法:
此外,git 对于 .ignore 配置文件是按行从上到下进行规则匹配的,意味着如果前面的规则匹配的范围更大,则后面的规则将不会生效;
别名
撤销Git操作
撤销提交
一种常见的场景是,提交代码以后,你突然意识到这个提交有问题,应该撤销掉,这时执行下面的命令就可以了。
上面命令的原理是,在当前提交后面,新增一次提交,抵消掉上一次提交导致的所有变化。它不会改变过去的历史,所以是首选方式,没有任何丢失代码的风险。
git revert 命令只能抵消上一个提交,如果想抵消多个提交,必须在命令行依次指定这些提交。比如,抵消前两个提交,要像下面这样写。
git revert 命令还有两个参数。
丢弃提交
如果希望以前的提交在历史中彻底消失,而不是被抵消掉,可以使用 git reset 命令,丢弃掉某个提交之后的所有提交。
git reset 的原理是,让最新提交的指针回到以前某个时点,该时点之后的提交都从历史中消失。
默认情况下,git reset 不改变工作区的文件(但会改变暂存区),--hard 参数可以让工作区里面的文件也回到以前的状态。
执行 git reset 命令之后,如果想找回那些丢弃掉的提交,可以使用 git reflog 命令,具体做法参考这里。不过,这种做法有时效性,时间长了可能找不回来。
替换上一次提交
提交以后,发现提交信息写错了,这时可以使用 git commit 命令的 --amend 参数,可以修改上一次的提交信息。
它的原理是产生一个新的提交对象,替换掉上一次提交产生的提交对象。
这时如果暂存区有发生变化的文件,会一起提交到仓库。所以,--amend 不仅可以修改提交信息,还可以整个把上一次提交替换掉。
修改上一次的 commit
撤销工作区的文件修改
如果工作区的某个文件被改乱了,但还没有提交,可以用 git checkout 命令找回本次修改之前的文件。
它的原理是先找暂存区,如果该文件有暂存的版本,则恢复该版本,否则恢复上一次提交的版本。
注意,工作区的文件变化一旦被撤销,就无法找回了。
从暂存区撤销文件
如果不小心把一个文件添加到暂存区,可以用下面的命令撤销。
上面的命令不影响已经提交的内容。
撤销当前分支的变化
你在当前分支上做了几次提交,突然发现放错了分支,这几个提交本应该放到另一个分支。
上面的操作等于是撤销当前分支的变化,将这些变化放到一个新建的分支。
跳转
子模块
有种情况经常会遇到:某个工作中的项目需要包含并使用另一个项目。也许是第三方库,或者你独立开发的,用于多个父项目的库。
现在问题来了:你想要把它们当做两个独立的项目,同时又想在一个项目中使用另一个。
假设你正在开发一个网站然后创建了 Atom 订阅。 你决定使用一个库,而不是写自己的 Atom 生成代码。你可能不得不通过 CPAN 安装或 Ruby gem 来包含共享库中的代码,或者将源代码直接拷贝到自己的项目中。如果将这个库包含进来,那么无论用何种方式都很难定制它,部署则更加困难,因为你必须确保每一个客户端都包含该库。 如果将代码复制到自己的项目中,那么你做的任何自定义修改都会使合并上游的改动变得困难。
Git 通过子模块来解决这个问题。子模块允许你将一个 Git 仓库作为另一个 Git 仓库的子目录。它能让你将另一个仓库克隆到自己的项目中,同时还保持提交的独立。
运行 git status
首先应当注意到新的 .gitmodules 文件。 该配置文件保存了项目 URL 与已经拉取的本地目录之间的映射:
如果有多个子模块,该文件中就会有多条记录。 要重点注意的是,该文件也像 .gitignore 文件一样受到(通过)版本控制。 它会和该项目的其他部分一同被拉取推送。 这就是克隆该项目的人知道去哪获得子模块的原因。
当你提交时,会看到类似下面的信息:
最后,推送这些更改:
大小写
git 默认对于文件名大小写是不敏感的,所以你修改了首字母大写,但是 git 并没有发现代码任何改动.
可以配置 git 使其对文件名大小写敏感
远程操作
多人协作的工作模式通常是这样:
首先,可以试图用
git push origin branch-name推送自己的修改;如果推送失败,则因为远程分支比你的本地更新,需要先用
git pull试图合并;如果合并有冲突,则解决冲突,并在本地提交;
没有冲突或者解决掉冲突后,再用
git push origin branch-name推送就能成功!如果
git pull提示"no tracking information",则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name
clone
git clone <版本库的网址> <本地目录名>
remote
fetch
git fetch 会使你与另一仓库同步,提取你本地所没有的数据,为你在同步时的该远端的每一分支提供书签. 这些分支被叫做 "远端分支",除了 Git 不允许你检出(切换到该分支)之外,跟本地分支没区别 —— 你可以将它们合并到当前分支,与其他分支作比较差异,查看那些分支的历史日志,等等.同步之后你就可以在本地操作这些.
上面命令表示,本地主机的当前分支是 master,远程分支是 origin/master.
取回远程主机的更新以后,可以在它的基础上,使用 git checkout 命令创建一个新的分支.
pull
基本上,该命令就是在 git fetch 之后紧接着 git merge 远端分支到你所在的任意分支.
pull 文件时和本地文件冲突
git stash 先将本地修改存储起来 这样本地的所有修改就都被暂时存储起来 .是用 git stash list 可以看到保存的信息:
暂存了本地修改之后,就可以 git pull 了.
还原暂存的内容 git stash pop stash@{0} 提示如下信息
意思就是系统自动合并修改的内容,但是其中有冲突,需要解决其中的冲突.
也可以放弃本地修改,直接覆盖之
push
github
github 开启二次验证后后,git push 验证权限失败
github 开启二次验证后,提交时密码用个人设置里的 Personal Access Token,不是账号密码
Git Push 避免用户名和密码方法
在 windows 中添加一个用户变量,变量名:HOME,变量值:%USERPROFILE%
进入
%HOME%目录,新建一个名为_netrc的文件,文件中内容格式如下:压缩 github 上的项目大小
下载工具 https://rtyley.github.io/bfg-repo-cleaner/
将下载好的 jar 文件放在要压缩的项目同级文件夹下,我这里以自己仓库为例
BFG 将更新提交以及所有分支和标记,此时还没有物理删除。
进入文件夹,使用
gc确认无误后,可提交至远程仓库
重建版本库
Github 进行 fork 后如何与原仓库同步
Git_LFS
Git Large File Storage (Git LFS) 是 Git 的开源扩展,使你能够像处理其他文本文件一样处理大文件。
安装
Windows: 访问 https://git-lfs.github.com/ 下载 exe 安装包
验证安装成功
配置
安装 [Git LFS] 后 (/articles/installing-git-large-file-storage/),需要将其与仓库中的大文件相关联。
如果仓库中存在要用于 GitHub 的现有文件,则需要先从仓库中删除它们,然后在本地将其添加到 Git LFS。
常见报错
Error with socks5 proxy
Git LFS 目前不支持 socks5 代理,换 http 代理