Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。发明人就是大名鼎鼎的Linus ,发明初衷为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。需要知道的是Git底层文件验证采用的是SHA-1,(SHA-1)哈希算法可以被用来验证文件。哈希算法有如下特点:
$ git config --list # 显示当前的Git配置
$ git config -e [--global] # 编辑Git配置文件
# 设置提交代码时的用户信息,是否加上全局--global自行决定,一般是直接设置全局的。用户邮箱,需要和你远程仓库保持一致不然你的contribution是不会被记录在远程仓库的
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"
# 常用的给命令起别名
$ git config --global alias.st status
$ git config --global alias.last 'log -1' # 别名 显示最后一次Commit
$ 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"
配置包括~/.gitconfig
(用户级别)和.git/config
(仓库级别),所有命令加上 --gloabal 就是指用户级别的配置。
$ mkdir project-name # 创建目录
$ cd project-name
$ git init [project-name] # 在当前目录新建一个Git代码库
$ git clone url # 下载项目的整个代码历史(包括各个分支提交记录等)
$ git remote add Aliases url # 为远程库取别名,用于push/pull,如 git pull origin master
$ git remote -v # 查看远程库信息
$ git remote rm Aliases
$ git add [* | file | dir] # 将文件、文件夹添加到暂存区(Index)
$ git add -p # 添加每个变化前,都会要求确认,对于同一个文件的多处变化,可以实现分次提交
$ git commit [file1 | file2] -m 'message' # 提交暂存区到仓库区
$ git commit -a #提交工作区自上次commit之后的变化,直接到仓库区,甚用
$ git commit -v #提交时显示所有diff信息
$ git commit --amend -m 'message' # 使用一次新的commit,替代上一次提交;也在代码无变化时用来修改message信息
$ git push [-u] origin master # 提交更改到远程仓库
$ git pull origin master # 拉取远程更改到本地仓库默认自动合并
删除文件也要慎重,现在举个例子,假设我在工作区add、commit了一个文件 a.txt
,
git status
git rm/add a.txt
git commit -m 'delete a.txt'
# 其他操作
$ git rm [file1] [file2] ... # 删除工作区文件,并且将这次删除放入暂存区
$ git rm --cached [file] # 停止追踪指定文件,但该文件会保留在工作区
$ git mv [file-original] [file-renamed] # 改名文件,并且将这个改名放入暂存区
$ git diff [file] # 默认是工作区文件和暂存区文件比较;
$ git diff HEAD [file] # 工作区和HEAD本地库比较
$ git checkout -- file # 把工作区的修改撤销
$ git reset HEAD file # 把暂存区的修改撤销掉(unstage)
$ git reset --hard HEAD^ # 把本地库的修改撤销掉(详细请看下面版本回退)
git log --pretty=oneline # 查看(从当前往后的)历史版本,HEAD表示当前版本
git reset --hard HEAD^ # 后退一个版本,一个 ^ 表示一个版本
git reset --hard HEAD~1 # 后退一个版本
git reset --hard commit_id # 后退或前进到某一个版本
git reflog # 查看版本变迁
关于git reset的参数做以下说明:
--soft
--mixed
--hard
因此,当然一般建议使用--hard
分支管理是git的一大特性,以下分支讲解来自廖学锋的官方网站。在Git里,默认有个分支叫master
分支。HEAD
严格来说不是指向提交,而是指向master
,master
才是指向提交的,所以,HEAD
指向的就是当前分支。
当我们创建新的分支,例如dev
时,Git新建了一个指针叫dev
,指向master
相同的提交,再把HEAD
指向dev
,就表示当前分支在dev
上:
从现在开始,对工作区的修改和提交就是针对dev
分支了,比如新提交一次后,dev
指针往前移动一步,而master
指针不变:
假如我们在dev
上的工作完成了,就可以把dev
合并到master
上。Git怎么合并呢?最简单的方法,就是直接把master
指向dev
的当前提交,就完成了合并:
合并完分支后,甚至可以删除dev
分支。删除dev
分支就是把dev
指针给删掉,删掉后,我们就剩下了一条master
分支:
$ git branch [-r|a| ] # 列出所有分支, r表示remote、a表示all,当前分支前会标星号
$ git branch [branch-name] # 新建一个分支,但依然停留在当前分支
$ git branch -d [branch-name] # 删除分支
$ git checkout -b [branch] # 新建一个分支,并转到新分支
$ git checkout [branch-name] # 切换分支
$ git checkout - # 切换到上一个分支
$ git merge [branch] # 合并指定分支到当前分支,Fast-forward模式
$ git merge --no-ff -m 'merge branch to current branch' [branch] # 禁用Fast-forward模式【推荐】
$ git checkout -b branch origin/branch # 创建分支并关联远程分支
$ git branch --set-upstream-to <branch-name> origin/<branch-name> # 如果创建的时候未关联,可以这样关联
当合并分支遇到上图情况时,就需要手动解决冲突:
手动根据实际业务需求修改好之后,再次提交即可:
git add test.txt
git commit -m 'fix conflict' test.txt
我们经常会看到某某软件对应v1.01,这就是Tag,每个Tag对应于一个commit,不可以移动,且创建的标签默认都只存储在本地,不会自动推送到远程。
# 想在master分支打一个标签
$ git checkout master
$ git tag [-m 'message'] v0.9
$ git log --pretty=oneline --abbrev-commit # 用这个命令查看历史commit_id
$ git tag v0.9 gt786b7
$ git tag # 查看当前分支有哪些Tag
$ git show <tagname> # 查看某个tag信息
$ git tag -d tag_name # 先删本地标签
$ git push origin :refs/tags/tag_name # 再删远程标签
$ git push origin <tagname> # 推送标签
$ git push origin --tags # 推送所有标签
登录方式有两种:账号登录、SSH免密登录,账号登录就不用写了,这里主要说一下SSH登录:
ssh-keygen -t rsa -C "[email protected]"
会在~/.ssh文件夹下生成id_rsa
(私钥,保存好)和id_rsa.pub
(公钥)两个文件,然后将公钥中的内容粘贴到下图位置:
关联远程库,主要是关系到工作流程,一种是你新加入一个项目,开始做一个已经有前辈在做的项目,这时候你要先去git服务器上拉取内容;还有一种情况是你做了一项工作一部分,要团队协作了,你将代码上传到git服务器,用git进行版本控制。
case1
mkdir dir_name
cd dir_name
git clone url # 即可拉取git上最新的内容
case2
# 先在git服务器上建立一个repository
git remote add origin project_url # 建立关联
git push -u origin master # 推送到服务器,第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
团队协作时的版本控制需要特别注意,因为你并不能更保证你现在的本地库有没有保持最新状态,可以按如下方式push:
git push origin branch_name
git pull
git push origin branch-name
多分支的提交会使历史线有很多的分叉,非常难以观察,这时候可以用到git rebase
,关于这一点可以参考rebase
在.gitignore文件中可以指定忽略的文件或目录,这些文件或目录将不会被提交。当然也可以通过全局配置core.excludesfile
来设置过滤规则。推荐大家参考github-gitignore,里面收集了不少常用的配置规则。以下介绍几个相关命令:
git add -f [file | dir]
文件被忽略时,强行添加某文件git check-ignore -v file
file被莫名忽略,八成.ignore文件写错了,check一下,找到错误 Git默认情况下会忽略空的文件夹,如果想要追踪控制空文件夹,根据惯例会在空文件夹下放置.gitkeep
文件。Anyway,其实可以放置任何你想放置的文件。
clone、pull、fetch区别
github.com
换成:githistory.xyz
或 github.githistory.xyz
或 github-history.netlify.com
就可以了。cd project_name # 进入项目
git checkout --orphan latest_branch # 创建"孤儿"分支并进入
git add -A;
git commit -am "first commit";
git branch -D master; # 删除master分支
git branch -m master; # 将孤儿分支重命名为master分支
git push -f origin master; # 强制push到远程库
Git是目前最优秀的版本控制软件,想要熟练它,多做协作项目就好了,总有你意想不到的惊喜等着你!