Git 简介
Git是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。分布式相比于集中式的最大区别在于开发者可以提交到本地,每个开发者通过克隆(git clone),在本地机器上拷贝一个完整的Git仓库。
初始化版本库
版本库是一个本地厂库,一个用户可以建立多个版本库,一般一个项目会建立一个版本库,这个版本库可以跟随用户的删除、修改操作,以便对这些操作实现维护。创建版本库的步骤如下:
git init # 初始化一个 git 仓库
echo "hello world" > readMe.md # 新建一个 readMe.md 文件
git add readMe.md # 添加当前工作区对该文件的修改到暂存区
git commit -m "init it" # 提交本次暂存区的修改到本地仓库
# 将本地仓库与远程仓库进行关联
git remote add origin https://github.com/ZhangDianPeng/gitTest.git
git push -u origin master # 将本地仓库当前分支与远程仓库 master 分支建立关联
工作区、暂存区、本地分支
Git 最核心的一个概念就是工作流:
- 工作区(Workspace)是电脑中实际的目录。
- 暂存区(Index)类似于缓存区域,临时保存你的改动。
- 仓库区(Repository),分为本地仓库和远程仓库。
git 常用操作命令
- git status 查看当前工作区的状态
- git clone 将远程仓库的克隆到本地仓库
- git add 将工作区的修改添加到暂存区
- add commit 将暂存区的修改提交到本地仓库
- git diff 查看工作区做了哪些修改
- git reset 回退所有的add操作
- git reset --hard 回退所有add操作,并强制删除上一次commit之后的所有修改
- git reset HEAD^ 退回本次commit操作,但不删除修改的数据
- git reset --hard HEAD^ 回退本次commit操作,并删除本次所有的修改数据,删除上一次commit之后的所有修改
- git reset --hard commitId 回退到指定commit节点
- git log 查看已经提交的所有commit
- git reflog 查看所有的操作历史,包含reset记录,被reset掉的commit,所以根据该命令可以reset回到未来
- git checkout file 让文件回到最近一次commit或者add状态,比reset的风险小
- git checkout branch 切换到指定分支
- git checkout -b branch 创建branch分支,并切换到branch分支
- git branch 查看所有本地分支
- git branch -d dev 删除dev分支
- git branch -D dev 强制删除一个没有被合并的分支
- git merge branch 将branch合并到当前分支,
- git merge branch --no-ff 加上--no-ff可以用普通模型合并,合并后有历史分支,如果不加--no-ff,那么若采用fast forward合并则看不出来曾经做过的合并
- git merge branch --squash 使用squash方式合并,把多次分支commit历史压缩为一次
- git rebase branch git merge 和 git rebase都是合并分支的意思,git merge会生成一个新的节点,之前的提交分开显示,而 git rebase不会形成新的节点,将两个分支提交融合成线性,看不出merge的过程
- git stash 将工作区和暂存区的内容保存在垃圾箱里,回到最近一次commit
- git stash list 查看stash过的所有记录
- git stash pop 将上一次stash掉的内容还原,此时会删掉stash list中相应的记录,原有add掉的代码会变成未被add的状态
- git stash apply 将上一次stash掉的内容还原,此时不会删掉stash list中的记录
- git stash drop 将上一次stash掉的内容从stash list中删掉
- git pull 默认将当前分支的内容从对应的远程拉下来
- git push 默认将当前分支的内容推向对应的远程分支
- git push origin dev 在当前分支将其它分支推向远程,如果第一次新建分支,必须使用该操作
- git pull origin dev 在当前分支将其它分支从远程拉下来,并merge到当前分支
- git tag v0.1 给最新的commit-id打上tag
- git tag v0.1 commit-id 给对应的commit-id打上tag
- git tag 查看所有标签列表
- git show v0.1 查看对应tag的信息
- git tag -d v0.1 删除某个tag
- git push origin v0.1 推送某个tag到远程
- git push origin --tags 推送所有tag到远程
- git push origin :refs/tags/v0.1 删除一个远程标签
- git config --global color.ui true git适当会显示不同的颜色作区分
- git config --global alias.st status 给命令重命名
- git fetch 将远程分支的代码更新到本地,此时需要使用origin/branch才能看到本地的更新
- git pull = git fetch + git merge
- git pull --brease = git fetch + git rebase
git merge 和 git rebase 的区别
假设有两个分支test和master如下:
D---E test
/
A---B---C---F master
当我们在把test分支merge到master分支时
- git merge
merge操作会生成一个新的节点,之前的提交分开显示:
D--------E
/ \
A---B---C---F----G test, master
- git rebase
rebase操作不会生成新的节点,是将两个分支融合成一个线性的提交
A---B---D---E---C'---F' test, master
当需要保留详细的合并信息的时候建议使用git merge,想要更好的提交树,使用rebase操作会更好一点。这样可以线性的看到每一次提交,并且没有增加提交节点
.gitignore
在git中如果想忽略掉某个文件,不让这个文件提交到版本库中,可以使用修改根目录中.gitignore文件的方法(如无,则需自己手工建立此文件)。这个文件每一行保存了一个匹配的规则例如:
logs/*.log
src/server/logs/*.log
src/server/logs/*.txt
src/webapp/src/css/
规则很简单,但是有时候在项目开发过程中,突然心血来潮想把某些目录或文件加入忽略规则,按照上述方法定义后发现并未生效,原因是.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:
git rm -rf coverage/
git commit -m "let coverage untracked and ignore"
Git 和 SVN 的区别
- git 是分布式的,svn 是集中式的,git 可以离线工作,而 svn 必须联网才能工作
- git 命令比较复杂,但功能强大,svn 相对容易上手
- git 分支只是指向某次提交的commit,创建简单迅速,svn分支是目录的拷贝,成本较高,并且svn没有本地分支概念