前言: 这是本人学习廖雪峰老师git教程的总结笔记! 适合快速入门并应用
git 是什么?
用 C 编写的分布式版本控制系统
分布式和集中式的区别?
- 分布式:每个人都有一个完整的代码版本库,只需要提交修改信息即可
- 集中式:代码归中央仓库管,写代码时需要下载至本地,写完后再推送到中央仓库中。
Git的安装
https://www.liaoxuefeng.com/wiki/896043488029600/896067074338496
https://www.jianshu.com/p/a152f82c5e4a
- 安装成功校验:Git Bash 能运行
- 完成安装设置:
在命令行设置:
git config --global user.name "name"
git config --global user.email "email"
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
注意git config命令的–global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
创建git仓库
!!! 注意:windows目录尽量不要包含中文
// 1.创建一个空目录
mkdir mydir
// 2. 切换
cd mydir
// 3. 查看
pwd
// 4.初始化
git init
-
初始化 看到.git隐藏文件及说明建立仓库成功!
-
二进制文件无法跟踪文件变化,只能知道文件大小改变了
千万不要使用Windows自带的记事本编辑任何文本文件。
原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,
他们自作聪明地在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题,
比如,网页第一行可能会显示一个“?”,明明正确的程序一编译就报语法错误,
等等,都是由记事本的弱智行为带来的。建议你下载Notepad++代替记事本,不但功能强大,而且免费!
记得把Notepad++的默认编码设置为UTF-8 without BOM即可:
添加文件到Git仓库,分两步:
-
使用命令git add ,注意,可反复多次使用,添加多个文件;
-
使用命令git commit -m ,完成。
- 添加版本控制文件/修改文件
git add readme.txt
- 提交
git commit -m "there wirte your commit"
- 查看文件修改状态
git status
- 查看不同
git diff <file>
- 查看提交日志
git log
// 查看分支树
git log --graph --pretty=oneline --abbrev-commit
- 回退版本
// 回退到最初版本
git reset --hard HEAD^
// 回退到指定版本 2133指的是该版本的id
git reset -- hard 2133
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区:
版本库(Repository)
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,
还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
git-repo
- 撤销修改(撤销工作区的修改)
git checkout -- <file>
- 添加到暂存区后撤销修改
1. HEAD代表当前最新版本
git reset HEAD <file>
2.
git checkout -- <file>
- 将本地仓库同步到远程仓库
git remote add origin git@github.com:michaelliao/learngit.git
// 首次本地提交到远程版本库
git push -u origin master
// 后续
git push origin master
- 远程版本库连接不上问题:
https://blog.youkuaiyun.com/qq_34446663/article/details/81106018
克隆
git clone <url>
example:
git clone git@github.com:michaelliao/learngit.git
git clone https://github.com/LovebuildJ/desktop-rest-manager.git
分支管理
- 创建分支
// 创建分支
git branch name
// 切换分支
git checkout name
// 创建并切换
git checkout -b name
- 切换分支
git checkout name
- 查看分支
git branch
- 合并分支(需要先切换到master)
// name 分支名称
git merge name
- 删除分支
git branch -d name
// 如果要丢弃一个没有被合并过的分支,可以通过 git branch -D <name>强行删除。
git branch -D <name>
- git checkout 有 撤销 和 切换分支。不太好理解。故切换分支可使用以下命令
// 创建并切换分支
git switch -c name
// 切换分支
git switch name
// 切换到已有的master分支
git switch master
- 分支管理策略
通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
下面我们实战一下–no-ff方式的git merge:
首先,仍然创建并切换dev分支:
git merge --no-ff -m "comment" branch-name
- BUG分支
软件开发中,bug就像家常便饭一样。有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,等等,当前正在dev上进行的工作还没有提交:
并不是你不想提交,而是工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug,怎么办?
幸好,Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:
// 保存
git stash
// 查看
git stash list
// 恢复
git stash apply
// 但是恢复后,stash内容并不删除,你需要用
git stash drop
// 来删除;
// 另一种方式是用
git stash pop
// 恢复的同时把stash内容也删了:
同样的bug,要在dev上修复,我们只需要把4c805e2 fix bug 101这个提交所做的修改“复制”到dev分支。注意:我们只想复制4c805e2 fix bug 101这个提交所做的修改,并不是把整个master分支merge过来。
为了方便操作,Git专门提供了一个cherry-pick命令,让我们能复制一个特定的提交到当前分支:
Git自动给dev分支做了一次提交,注意这次提交的commit是1d4b803,它并不同于master的4c805e2,因为这两个commit只是改动相同,但确实是两个不同的commit。用git cherry-pick,我们就不需要在dev分支上手动再把修bug的过程重复一遍。
git cherry-pick 4c805e2
- 多人协作
当你从远程仓库克隆时,实际上Git自动把本地的master分支和
远程的master分支对应起来了,并且,远程仓库的默认名称是origin。
要查看远程库的信息,用
git remote
或者,用
git remote -v
显示更详细的信息:
推送分支
推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:
git push origin master
如果要推送其他分支,比如dev,就改成:
git push origin dev
你的小伙伴已经向origin/dev分支推送了他的提交,而碰巧你也对同样的文件作了修改,并试图推送:
$ cat env.txt
env
$ git add env.txt
$ git commit -m "add new env"
[dev 7bd91f1] add new env
1 file changed, 1 insertion(+)
create mode 100644 env.txt
$ git push origin dev
To github.com:michaelliao/learngit.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to 'git@github.com:michaelliao/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已经提示我们,
先用
git pull
把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:
$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:
git branch --set-upstream-to=origin/<branch> dev
git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:
$ git branch --set-upstream-to=origin/dev dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
再pull:
$ git pull
Auto-merging env.txt
CONFLICT (add/add): Merge conflict in env.txt
Automatic merge failed; fix conflicts and then commit the result.
这回git pull成功,但是合并有冲突,需要手动解决
,解决的方法和分支管理中的解决冲突完全一样。解决后,提交,再push:
$ git commit -m "fix env conflict"
[dev 57c53ab] fix env conflict
$ git push origin dev
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 621 bytes | 621.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
7a5e5dd..57c53ab dev -> dev
- 标签
然后,敲命令git tag 就可以打一个新标签:
$ git tag v1.0
可以用命令git tag查看所有标签:
$ git tag
v1.0
默认标签是打在最新提交的commit上的。有时候,如果忘了打标签,比如,现在已经是周五了,但应该在周一打的标签没有打,怎么办?
方法是找到历史提交的commit id,然后打上就可以了:
$ git log --pretty=oneline --abbrev-commit
12a631b (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101
4c805e2 fix bug 101
e1e9c68 merge with no-ff
f52c633 add merge
cf810e4 conflict fixed
5dc6824 & simple
14096d0 AND simple
b17d20e branch test
d46f35e remove test.txt
b84166e add test.txt
519219b git tracks changes
e43a48b understand how stage works
1094adb append GPL
e475afc add distributed
eaadf4e wrote a readme file
比方说要对add merge这次提交打标签,它对应的commit id是f52c633,敲入命令:
$ git tag v0.9 f52c633
再用命令git tag查看标签:
$ git tag
v0.9
v1.0
注意,标签不是按时间顺序列出,而是按字母排序的。可以用
git show <tagname>
查看标签信息
- 如果标签打错了,也可以删除:
$ git tag -d v0.1
Deleted tag 'v0.1' (was f15b0dd)
因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。
如果要推送某个标签到远程,使用命令git push origin :
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
* [new tag] v1.0 -> v1.0
或者,一次性推送全部尚未推送到远程的本地标签:
$ git push origin --tags
Total 0 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
* [new tag] v0.9 -> v0.9
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:
$ git tag -d v0.9
Deleted tag 'v0.9' (was f52c633)
然后,从远程删除。删除命令也是push,但是格式如下:
$ git push origin :refs/tags/v0.9
To github.com:michaelliao/learngit.git
- [deleted] v0.9
有没有经常敲错命令?比如git status?status这个单词真心不好记。
如果敲git st就表示git status那就简单多了,当然这种偷懒的办法我们是极力赞成的。
我们只需要敲一行命令,告诉Git,以后st就表示status:
$ git config --global alias.st status
好了,现在敲git st看看效果。
当然还有别的命令可以简写,很多人都用co表示checkout,ci表示commit,br表示branch:
$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.br branch
以后提交就可以简写成:
$ git ci -m "bala bala bala..."
–global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。
在撤销修改一节中,我们知道,命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区。既然是一个unstage操作,就可以配置一个unstage别名:
$ git config --global alias.unstage 'reset HEAD'
当你敲入命令:
$ git unstage test.py
实际上Git执行的是:
$ git reset HEAD test.py
配置一个git last,让其显示最后一次提交信息:
$ git config --global alias.last 'log -1'
这样,用git last就能显示最近一次的提交:
$ git last
commit adca45d317e6d8a4b23f9811c3d7b7f0f180bfe2
Merge: bd6ae48 291bea8
Author: Michael Liao <askxuefeng@gmail.com>
Date: Thu Aug 22 22:49:22 2013 +0800
merge & fix hello.py
甚至还有人丧心病狂地把lg配置成了:
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-lg
为什么不早点告诉我?别激动,咱不是为了多记几个英文单词嘛!
配置文件
配置Git的时候,加上–global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用。
配置文件放哪了?每个仓库的Git配置文件都放在.git/config文件中:
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = git@github.com:michaelliao/learngit.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[alias]
last = log -1
别名就在[alias]后面,要删除别名,直接把对应的行删掉即可。
而当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中:
$ cat .gitconfig
[alias]
co = checkout
ci = commit
br = branch
st = status
[user]
name = Your Name
email = your@email.com
配置别名也可以直接修改这个文件,如果改错了,可以删掉文件重新通过命令配置。
搭建git服务器
https://www.liaoxuefeng.com/wiki/896043488029600/899998870925664