windows 10 下GIT版本控制
https://www.liaoxuefeng.com/wiki/896043488029600
上面的网站讲得很详细。
下载GIT:https://git-scm.com/downloads
一.基本操作
1.进入任意文件
cd E:\practice
2.创建空目录
mkdir learngit
cd learngit
pwd % 显示当前路径
ls %显示当前路径下所有文件
查看文件内容cat
3.初始化
git init
把该目录变成GIT可以管理的仓库。
4.添加任意数量的文件到暂存区
git add readme.txt
cat readme.txt %查看文本内容
5.将暂存区的文件加入仓库
git commit -m
“写入名为readme的文件”
commit可以一次提交很多文件,可以多次add不同文件,然后一起提交。例如:
$ git add file1.txt
$ git add file2.txt file3.txt
$ git commit -m “add 3 files.”
而 -m 的作用是记录一条历史消息
也可使用git commit -am 一次将仓库中所有修改了的文件都加入到当前提交中(新建的文件无法commit)。
6.git diff 、 git log 、git reflog
git diff [filename] 查看工作区和暂存区的区别
git diff --cached 查看暂存区和仓库的区别
git diff HEAD 查看工作区和仓库的区别
如果没有差别Git不会有相应。
git log 查看所有提交日志 (win10下git log后用q返回)
git log --pretty=oneline 查看所有提交日志简化版
git log --graph可以看到分支合并图。
git reflog 记录每一次命令
查看log后使用q退出
7.版本回退与撤销修改git reset、git checkout
git reset --hard HEAD^ %返回上个版本%hard会将暂存区清空,将上次提交的内容恢复到本地,且本地的内容也会被上次提交的内容覆盖,不会保留修改。,还有mixed(默认),和soft两种模式。
git reset –soft HEAD~1
回退一个版本,不清空暂存区,将已提交的内容恢复到暂存区,不影响原来本地的文件(未提交的也不受影响)
git reset (–mixed) HEAD~1
回退一个版本,且会将暂存区的内容和本地已提交的内容全部恢复到未暂存的状态,不影响原来本地文件(未提交的也不受影响)
HEAD^^表示上上个版本。 HEAD~100表示上100个版本
根据git reflog 查出的commit id 可以返回过去和未来的任意一个版本,例如:
git reset --hard df66d %commit id 没有必要全输。
HEAD指针,指向当前版本。
git checkout – [filename] 回到最近一次commit或add的状态,即丢弃所有未add的修改,用仓库里的版本替换工作区的文件。
如果修改后add了,应该先git reset HEAD [filename] 丢弃暂存区中的内容,之后 git checkout – [filename]丢弃所有修改。
工作区–>暂存区–>仓库(版本库)
add 将工作区内容送入暂存区
commit 将暂存区内容送入仓库
8.删除文件
rm [filename] 删除工作区文件
1.如果你用 rm [filename]
删除文件,那就相当于只删除了工作区的文件,如果想要恢复,直接用git checkout -- <file>
就可以 2.如果你用的是git rm删除文件,那就相当于不仅删除了文件,而且还添加到了暂存区,需要先git reset HEAD ,然后再git checkout -- <file>
3.如果你想彻底把版本库的删除掉,先git rm,再git commit 就ok了
git rm命令慎用,git rm -f * 更要慎用。
git rm -r 文件夹/ % 删除文件夹 如果没有后面的/,则只能删除空文件夹
查看和修改用户名
git config user.name
git config user.email %查看
git config --global user.name "your name"
git config --global user.email "your email" %修改
二.github远程版本控制
1.注册GitHub帐号
使用qq浏览器无法注册,改用火狐浏览器
2.创建SSH key
本地Git仓库和GitHub仓库之间的传输是通过SSH加密
修改用户主目录, 每次打开主目录为 c:\admin 修改为 E盘
之后在主目录下创建SSHkey:
$ ssh-keygen -t rsa -C “youremail@example.com”
邮箱为自己注册GitHub的邮箱
3.ADD SSH key
id_isa为私钥 id_isa.pub为公钥。把公钥的内容添加到GitHub上,可是添加多个公钥,因此可以多台电脑推送
4.添加远程库
先在GitHub网站上建一个名为learngit 的 new repository,之后将本地库与远程库关联$ git remote add origin git@github.com:michaelliao/learngit.git
michaelliao改为自己的github用户名。origin为远程库的名字,可以更改。
之后$ git push -u origin master
本地库内容推送,第一次推送master分支使用 -u,不仅将master推送到GitHub,还会把本地的master分支和远程的master分支关联起来。之后的推送可以简化为:git push origin master
第一次使用clone或push时,会受到SSH警告,yes即可。
5.从远程库克隆
建一个名为 gitskills 的repository。勾选Initialize this repository with a README,这样GitHub会自动为我们创建一个README.md文件。
之后在git bash上任意目录下输入:
git clone git@github.com:xxxxx/gitskills.git
还可以使用:
git clone git@https://github.com/michaelliao/gitskills.git
xxxxx和michaelliao都改成自己的用户名。
Git支持多种协议,默认使用ssh协议,也可以使用https协议等,但通过ssh支持的原生git协议速度最快。
6.分支管理
git鼓励使用大量分支。
创建分支git branch dev
切换到新的分支git checkout dev
或者git switch <name>
查看分支git branch
创建并切换到新的分支git checkout -b dev
或者git switch -c name
合并某分支到当前分支git merge <name>
,没有冲突情况下为快速合并Fast-forward。
删除分支git branch -d <name>
前面的撤销修改是git checkout - - [file]
所以切换分支时使用switch
更容易理解。
对于所有分支而言, 工作区和暂存区是公共的。如果在新的分支修改没有add就切换回原分支add,commit,则相当于在原来的分支add,commit。如果在新分支add了,返回原分支commit也相当于在原分支add,commit
git stash切换分支进行修改前贮存
总的来说,就是,在分支下进行的工作,如果不commit的话,回到master,就会显示出你在分支下你添加的工作。这个时候,你在master下修改完bug提交后,正在分支进行的工作也会提交了。为了避免这个情况,你就在分支下,git stash将工作隐藏,这个时候,切换到master时候,修改了bug,提交。分支的内容不会被提交上去。
7. 解决冲突
在不同的分支上,修改了不同内容,合并时会出现冲突。例如:
git switch -c dev
在该分支下修改readme.txt添加一行文本:i like poony.
之后。
git add readme.txt
git commit -m "poony"
git switch master
回到master分支。在readme.txt中发现新添加的i like poony
消失。添加新的一行文本i like ponys
之后。
git add readme.txt
git commit -m "ponys"
尝试合并:
git merge dev
出现错误:
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
并且文本中出现:
<<<<<<< HEAD
i like ponys.
=======
i like poony!
>>>>>>> dev
Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容。
vscode中可以直接点击选择采用哪种更改,或者保留双方更改。也可以修改某一个分支消除冲突。最后合并,此时查看git log。
git log --graph --pretty=oneline --abbrev-commit
* d8aebfa conflict fixed
|\
| * 0dbdaeb and simple
* | 6b6bb2a & simple
|/
出现类似上面的的格式,因为我用vscode直接点击,这个是上次合并的。
git log --graph
可以查看合并分支图,--pretty=oneline
查看简化后log,--abbrev-commit
简化前面的代号?
最后删除dev分支即可。
**发现vscode点击后并没有合并,,,只是在屏幕上显示某一个更改而已。
删除dev时出错,(若强制删除用git branch -D dev
)此时再次merge仍有冲突,退出merge,git merge --quit
。修改readme.txt,add,commit,merge。
8.分支管理技巧
合并时,如果可能,git就默认使用快速模式Fast forward
,**该模式下删除分支,会失去分支信息。**而使用--no-ff
可以禁用该模式。
git merge --no-ff -m "merge with no-ff" dev
合并。
删除git branch -d dev
之后查看日志。
git log --graph --pretty=oneline --abbrev-commit
9.bug分支
如果bug不在 当前分支(dev) 下修改的几个文件中,需要先git stash
把修改的文件隐藏,之后git switch -c bug001
在bug001下对bug进行修复,add,commit
回到master分支,git merge --no-ff -m "xxx" bug001
之后删除分支,回到dev分支,使用git cherry-pick xxxxx
将bug修复所做的提交复制过来,最后git stash pop
或者git stash apply + git stash drop
回复并删除贮藏,继续进行修改。
如果bug在 当前分支(dev) 下修改的几个文件中,在dev下stash
,之后修复bug+add + commit
,切换master,cherry-pick
,回到devpop
后继续修改。
10.feature分支
开发新功能最好新建分支feature_xx,当需要舍弃违背合并的分支时,使用-D,进行删除。
git branch -D feature_xx
11.多人协作
git remote
:查看远程库,git remote -v
:查看远程库详细信息,显示抓取和推送的详细地址。
git push origin master
、git push origin dev
可以将本地分支推送到远程库,master是主分支,dev是开发分支,因此都要时刻同步,而bug分支,和功能开发的feature分支不需要同步。
git clone git@github.com:username/repositoryname.git
克隆远程库到本地,克隆时只会克隆master分支,可以使用git branch
查看。
若想在dev分支上开发,需要建立远程origin的dev分支到本地,git checkout -b(switch -c) branch-name origin/branch-name
,本地分支和远程分支最好名称一致。
如果远程dev分支已经被修改,推送时会出错,需要使用pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:
直接git pull会失败,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:
git branch --set-upstream-to=origin/dev dev
或git branch --track origin/dev dev
之后git pull
,解决冲突commit,push。
关联以后就不需要重新关联了,直接切换到该分支,pull,master分支在第一次推送至已经关联。即第一次推送时使用-u就可以关联本地分支和远程分支
- The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to.旧的指令git branch --set-upstream
branch-name origin/branch-name已经要被移除。
12.rebase
git的文档(https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%8F%98%E5%9F%BA) 就清晰了。就使用过程来说:只对尚未推送或分享给别人的本地修改执行变基操作清理历史; 从不对已推送至别处的提交执行变基操作
原网站说,如果pull下来有冲突,解决冲突合并后,log不是直线,因此需要rebase使变得好看,实际需要先将冲突文件先add,再commit,再rebase,这时再手动修改代码解决冲突,执行git add . 再执行 git rebase --continue 就有效果了。这时直接git push 到远程仓库即可。
但是不应该对已推送的提交执行rebase,因此不用上述的复杂步骤,只需整理本地log时使用rebase即可。
git rebase
13.标签管理
标签指向commit。先切换回需要打标签的分支:
git switch master
---->git tag v1.0
对之前的commit打标签,找到历史的commit id:
git log --pretty=oneline
---->git tag v0.9 09bead4
创建带有说明的标签:
git tag -a v0.1 -m "version 0.1 released" 1094adb
查看所有标签及查看标签信息:
git tag
、git show tagname
推送标签到远程或推送所有本地标签到远程:
git push origin v1.0
、git push origin --tags
删除本地标签及删除远程标签:
git tag -d v1.0
、git push origin :refs/tags/v1.0
冒号在这里,前面为空,即将一个“空”的标签推送给对应的标签,即删除
三.参与开源项目
github
1.在别人的仓库里点“Fork”就在自己的账号下克隆了一个仓库。
2.从自己的账号下clone,git clone git@github.com:username/rname.git
,一定要从自己的账号下clone仓库,这样才能推送修改。如下图关系:
3.添加新功能后往自己的远程库推送,可以在GitHub上发起一个pull request。看看官方是否接受。
码云
gitee.com
国内的github,提供免费的私有库。
关联多个远程库时,使用不同的名称标识远程库:
git remote add github git@github.com:michaelliao/learngit.git
git remote add gitee git@github.com:michaelliao/learngit.git
推送时:
git push github master
,git push gitee master
分别推送。
git remote -v
查看远程库信息。
四.自定义GIT
忽略文件
每次git status都会显示Untracked files。
1.在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore
2.加上你自己定义的文件,最终得到一个完整的.gitignore文件:
Windows:
Thumbs.db
ehthumbs.db
Desktop.ini
Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build
My configurations:
db.ini
deploy_key_rsa
3.最后把.gitignore
也提交到Git!!!,就完成了!当然检验.gitignore的标准是git status命令是不是说working directory clean
。
4.有些时候,想添加一个文件到Git,但发现添加不了,原因是这个文件被.gitignore忽略了,用-f强制添加到Git:
git add -f App.class
5.如果.gitignore写得有问题,需要找出来到底哪个规则写错了,可以用git check-ignore
命令检查:
$ git check-ignore -v App.class
.gitignore:3:*.class App.class
可以知道是应该修改第几行出现的问题。
配置别名
配置别名简化操作:
$ git config --global alias.st status
$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.br branch
$ git config --global alias.unstage 'reset HEAD'
$ git config --global alias.last 'log -1'
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"
分别是status,checkout,commit,branch,reset HEAD,log -1(查看上次提交)。
以及查看所有提交的简化。
不可以将git简化,ga表示git add无法实现。
如果没有--global
所有的配置都在.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]后面,要删除别名,直接把对应的行删掉即可。
加上--global
后的配置文件,放在用户主目录下的一个隐藏文件.gitconfig
中:
$ cat .gitconfig
[alias]
co = checkout
ci = commit
br = branch
st = status
[user]
name = Your Name
email = your@email.com
配置别名也可以直接修改这个文件,如果改错了,可以删掉文件重新通过命令配置。
搭建git服务器
搭建Git服务器需要准备一台运行Linux的机器,推荐用Ubuntu或Debian,这样,通过几条简单的apt命令就可以完成安装。
1.安装git
$ sudo apt-get install git
2.创建一个git用户,用来运行git服务:
$sudo adduser git
3.创建证书登录
收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。
4.初始化Git仓库
先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:
$ sudo git init --bare sample.git
Git就会创建一个裸仓库,裸仓库没有工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git:
$ sudo chown -R git:git sample.git
5.禁用shell
出于安全考虑,第二步创建的git用户不允许登录shell,这可以通过编辑/etc/passwd文件完成。找到类似下面的一行:
git:x:1001:1001:,,,:/home/git:/bin/bash
改为:
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell
6.克隆远程库
$ git clone git@server:/srv/sample.git
Cloning into 'sample'...
warning: You appear to have cloned an empty repository.
剩下的推送就简单了。
- 要方便管理公钥,用Gitosis;
- 要像SVN那样变态地控制权限,用Gitolite。
总结
git常用指令总结:
Git Cheat Sheet
git官网:
http://git-scm.com
- 学了挺长时间的,确实学到了一个节省时间的技能,感谢廖老师