1. 概念
- github:git远程仓库
- git:版本控制系统
版本控制系统:集中式(svn)和分布式(git),分布式无中央服务器,每个人都有一份完整的版本库,多人协作时,推送自己修改的给其他人,其他人就可以看到了,不用联网
跟踪文本的改动,图片、视频等二进制只能记录文件大小的变化。采用UTF-8编码(只用notepad等编辑器)- 工作区:自己本地电脑的文件夹
- 版本库:.git文件,git的版本库
- 暂存区:git版本库中存了很多东西,包括称为stage(index)的暂存区,git自动创建的第一个分支master,以及指向master的指针HEAD。
git add:把文件添加到暂存区
git commit:把暂存区的所有内容提交到当前分支(默认就是master)
2. PowerShell命令
- cd f: 到f盘
- ls 列出目录及文件名
- pwd 显示当前目录
- rm app.js 删除文件或者目录
- cat app.js 打印到命令行,查看app.js文件
- mkdir learngit 创建目录
- cd learngit 切换目录
3. git配置
- –global参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用,放在用户主目录(C:\Users\lin-ss)下的一个隐藏文件.gitconfig中。即C:\Users\lin-ss.gitconfig。
没有–global只针对当前的仓库起作用。在.git/config文件中
git config --global user.name “lilin”
git config --global user.email “1375252148@qq.com”
git config --global color.ui true 显示颜色
git config --global alias.st status 设置别名,用git st代替git status
git config --global alias.last “log -s” git last 显示最后一次提交信息
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”
- .gitignore 文件 在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。.gitignore文件本身要放到版本库里,并且可以对.gitignore做版本管理!
忽略文件的原则是:
(1)忽略操作系统自动生成的文件,比如缩略图等;
(2)忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
(3)忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
有些时候,你想添加一个文件(app.class)到Git,但发现添加不了,原因是这个文件被.gitignore忽略了。可以用-f强制添加到Git;也可以用git check-ignore命令检查,看是哪条规则出问题了再修改该规则。
git add -f app.class 强制添加到git
git check-ignore -v app.class 检查哪条规则出问题了
4. git初始化提交
- git init 初始化当前目录为Git可以管理的仓库
- git add app.js 把文件添加到仓库
- git commit -m “fn:test” 把文件提交到仓库,-m “修改内容等”本次提交说明,可以多次add,一次commit
5. git查看
- git status 查看仓库当前状态
- git diff – app.js 查看修改内容(自己本地工作区和仓库最新版本(即某个分支)比)
- git log 查看版本提交日志(每次commit的说明)。退出该命令用q
- git reflog 查看命令历史
- git rm app.js 删除文件
6. git版本管理
- git checkout – app.js || git restore app.js
丢弃工作区修改。–很重要,没有表示切换分支。add前或者commit前修改工作区(回到最近一次git commit或git add时的状态),可以回退到仓库最新版本(修改和删除都可以还原),或者回退到和暂存区一样。
- git reset HEAD app.js || git restore --staged app.js
把暂存区的修改撤销掉(unstage),重新放回工作区,再git checkout丢弃工作区修改。commit前。
- git reset --hard HEAD^1
回退到上一个版本。一次commit就是一次快照,可以回退到某一个版本。HEAD(当前版本)、HEAD(上一个版本)、HEAD^(上上个版本)、HEAD~100(往上100个版本)。commit后,推送远程仓库前。
- git reset --hard commit-id
回到指定commit版本id的版本。commit-id(很长的一组数字,可以自动补全)。
7. git远程仓库github
- ssh-keygen -t rsa -C “1375252148@qq.com”
本地git仓库和远程github仓库传输要通过ssh加密(c/users/lin-ss/.ssh)id_rsa(私钥)和id_rsa.pub(公钥,放到github的ssh下)
- git remote add origin git@github.com:d3lin/learngit.git
关联本地learngit仓库与远程的github的learngit仓库。远程库的名字是origin,git默认的。
- git push -u origin master || git push -u origin local-branch-name:romote-branch-name
推送本地仓库内容到远程仓库,实际上是把当前分支master推送到远程仓库。-u是把本地的master分支和远程的master分支关联,以后再推送就可以不写-u,直接写git push origin master。
- git clone git@github.com:d3lin/learngit.git
从别人github上那复制(fork)仓库到自己的github上,要先克隆(clone),再拉到本地修改,修改好后,推送到自己的github上,如果你想要把这个修改推送给别人,可以pull request,等待别人接受。(别人的远程仓库-自己的远程仓库-自己的本地仓库)
8. git分支
- 创建一个独立的分支开发自己的功能,别人看不到,不影响其他人工作,自己随时提交管理等,都做好了后一次性合并到原来的分支。
- 每次提交,git都会把他们生成一条时间线(每次提交组成的线),这条时间线就是分支。例如master。HEAD指向当前分支,当前分支指向提交(这条分支时间线的最新的那版提交)。
- 在创建的dev分支上工作,然后合并到主分支上,再删除该分支,安全。合并前主分支上是看不到dev分支上修改提交等操作的。
- 当Git无法自动合并分支时,就必须首先解决冲突。解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容。
git branch dev 创建dev分支
git checkout dev || git switch dev 切换到dev分支
git checkout -b dev || git switch -c dev 创建并切换到dev分支
git branch 查看当前分支
git branch -d dev 删除dev分支(merge后删除)
git log --graph 查看分支合并图
git log --graph --pretty=oneline --abbrev-commit 一行,缩写的图表
git merge dev 把dev分支合并到当前分支
git merge --no-ff -m “merge with no-ff” dev
- 准备合并dev分支,请注意–no-ff参数,表示禁用Fast forward。因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
合并分支时,加上–no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
9. 修复bug
- 首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支;
- 修复bug时,我们会通过创建新的bug分支(例如issue-101)进行修复,然后合并,最后删除;
- 当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再在原来的工作现场分支上git stash pop,回到工作现场;
- 在master分支上修复的bug,想要合并到当前dev分支,可以用git cherry-pick <commit>命令,把bug提交的修改“复制”到当前分支,避免重复劳动。
git stash 把当前工作现场“储藏”起来,等以后恢复现场后继续工作
git stash list 查看所有工作现场
git stash apply 恢复现场,但是恢复后,stash内容并不删除,你需要用git stash drop来删除
git stash drop 删除已经恢复的工作现场
git stash pop 恢复的同时把stash内容也删除
git stash apply stash@{0} 多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash
git cherry-pick commit-id 复制一个特定的提交到当前分支
dev分支是早期从master分支分出来的,所以,这个bug其实在当前dev分支上也存在。同样的bug,要在dev上修复,我们只需要把4c805e2 fix bug 101这个提交所做的修改“复制”到dev分支。就不需要在dev分支上手动再把修bug的过程重复一遍。
那么直接在dev分支上修复bug,然后在master分支上“重放”行不行?当然可以,不过你仍然需要git stash命令保存现场,才能从dev分支切换到master分支。
git branch -D 强行删除(丢弃一个没有合并的分支)
添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。
git remote 查看远程库信息
git remote -v 显示更详细的远程库信息
git push origin dev 推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上。远程仓库的默认名称是origin。
git checkout -b dev origin/dev 创建远程origin的dev分支到本地。从远程库clone时,默认情况下,只能看到本地的master分支。
10. 多人协作的工作模式
- 首先,可以试图用git push origin 推送自己本地的修改到origin;
- 如果推送失败,则因为远程分支比你的本地要新,需要先用git pull抓取远程的分支到本地,试图合并;
- 如果合并有冲突,则解决冲突,并在本地提交;
- 没有冲突或者解决掉冲突后,再用git push origin 推送就能成功!
- 如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to origin/。
- 多人在同一个分支上协作时,很容易出现冲突。即使没有冲突,后push的童鞋不得不先pull,在本地合并,然后才能push成功。
git fetch origin master 将远程主机的最新内容拉到本地,不进行合并
git pull origin master 将远程主机的master分支最新内容拉下来后与当前本地分支直接合并 fetch+merge
git pull <远程主机名> <远程分支名>:<本地分支名>;
例如:git pull origin master:feature-wxDemo
git rebase 可以把本地未push的分叉提交历史整理成直线。使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。
- 原本分叉的提交现在变成一条直线了!这种神奇的操作是怎么实现的?其实原理非常简单。我们注意观察,发现Git把我们本地的提交“挪动”了位置,放到了f005ed4 (origin/master) set exit=1之后,这样,整个提交历史就成了一条直线。rebase操作前后,最终的提交内容是一致的,但是,我们本地的commit修改内容已经变化了,它们的修改不再基于d1be385 init hello,而是基于f005ed4 (origin/master) set exit=1,但最后的提交7e61ed4内容是一致的。
11. 标签
发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。
所以,tag就是一个让人容易记住的有意义的名字,它跟某个commit绑在一起。
git tag v1.0 新建一个标签,默认指向HEAD(当前分支最新的commit上),也可以指定一个commit-id
git tag v1.1 commit-id 如果忘了打标签,方法是找到历史提交的commit id
git tag -a v1.2 -m “说明” 创建带有说明的标签,用-a指定标签名,-m指定说明文字
git tag 查看所有标签
git show v1.1 查看标签信息
git tag -d v1.0 删除标签(因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。)
git push origin v1.0 推送标签到远程
git push origin --tags 推送全部尚未推送到远程的本地标签
如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除;然后,从远程删除。代码如下:
git tag -d v1.0
git push origin :refs/tags/v1.0