git add
& git commit
git当中的add
和commit
与svn有所区别原因:分布式vs集中式
由于git的分布式决定了我们每个人的电脑上都是一个完整的版本库(repository),因此add
和commit
都是相对于自己本地的版本库而言的。
版本库里存了很多东西,其中最重要的就是:
master
,以及指向master的一个指针叫HEAD
。HEAD
HEAD
意思是当前分支的最新版本,但其实它直接指向的是当前分支。
如果只有一个主分支,即主干master
,那HEAD
指向的是master
,而master
再指向于最新版本
$ git add a.txt // 添加某文件到本地版本库的暂存区
$ git add b.txt
$ git add . // 添加所有non-version文件到本地库暂存区
$ git commit -m "add 2 files" // 提交暂存区内所有文件到分支(如master)
添加文件到Git仓库,分两步:
git add <file>
—— 暂存区
注意,可反复多次使用,添加多个文件;git commit
完成。—— 分支
注意,commit之后,暂存区就会被清空ps. 这时只是添加到本地库,而不是远程的版本库github
git remote add origin git@server-name:path/repo-name.git
关联后,使用命令git push -u origin master第一次推送master分支的所有内容;
此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;
$ git clone git@github.com:michaelliao/learngit.git
...
$ git branch
*master
当使用clone命令克隆一个远程库时,默认情况下,只能看到本地的master分支。
如果想要获取dev分支,在上面开发,怎么办?
// 必须创建远程origin的dev分支到本地
$ git checkout -b dev origin/dev
$ git remote
origin
$ git remote -v // 详细信息
octocat https://github.com/octocat/Spoon-Knife.git (fetch)
octocat https://github.com/octocat/Spoon-Knife.git (push)
origin https://github.com/zfengqi/Spoon-Knife.git (fetch)
origin https://github.com/zfengqi/Spoon-Knife.git (push)
// 上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。
$ git push origin master // 指定本地分支,然后就会推送到对应的分支去
$ git push origin dev
因为远程分支版本比你的本地的要新,需要先用git pull
试图合并,即update代码
如果git pull
合并有冲突,则需要解决冲突,并在本地提交;
如果git pull提示 no tracking information,则说明本地分支和远程分支的链接关系没有创建
$ git branch --set-upstream <branch-name> <origin/branch-name>
HEAD
指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令$ git reset --hard commit_id
$ git reset --hard HEAD^ // 回滚上个版本
$ git reset --hard HEAD^^ // 回滚到上两个版本
$ git reset --hard HEAD~100 // 回滚到前100个版本
$ git log
commit 5a396f23af1729fa0c0049c58d42fe0d71541665
Author: kei <zfengqi90@gmail.com>
Date: Fri Jul 10 15:20:21 2015 +0800
Update README.md
commit e325faab05ad640d1e1dc31873dfd362b9c00a92
Author: zhangfengqi <jackyzfq@qq.com>
Date: Fri Jul 10 12:50:58 2015 +0800
javascript继承总结
//如果嫌输出信息太多,看得眼花缭乱的,可以试试
$ git log --pretty=oneline
// 退出或者终止log 按q
git reflog
查看命令历史,以便确定要回到未来的哪个版本 $ git reflog
9a2f804 HEAD@{0}: pull: Merge made by the 'recursive' strategy.
3bb1509 HEAD@{1}: commit: 函数柯里化总结
e325faa HEAD@{2}: commit: javascript继承总结
bd0213d HEAD@{3}: clone: from https://github.com/zfengqi/blog-and-note.git
用命令**git checkout -- <file>
**
命令git checkout -- readme.txt
意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
ps. 修改的是工作区的文件内容,即本地文件。
分两步
git reset HEAD <file>
,就回到了场景1,即撤销了对这个文件的add操作!git checkout -- <file>
的含义git checkout -- <file>
其实是用版本库里的版本(包括暂存区)替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
在SVN当中,创建和切换分支的速度是很慢的,而在git里面就是1秒钟的事。
$ git branch // 查看已有的分支
$ git branch new_branch // 创建分支(并没有切换)
$ git checkout new_branch // 切换分支
$ git checkout -b new_branch // 创建+切换到new_branch分支
$ git branch -d new_branch // 删除分支
$ git branch -D <name> //如果要丢弃一个没有被合并过的分支,可以强行删除
$ git merge new_branch // 在主干master上进行merge
Updating d17efd8..fec145a
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
Fast-forward
告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。
当前分支如果有没add和commit的内容的话,是没法切换到其他分支的
如果暂时并不想commit,但是又有需要切换到其他分支的话,怎么办?
$ git stash // 把当前工作现场“储藏”起来,等以后回来这个分支再继续工作
$ git stash list
stash@{0}: WIP on dev: 6224937 add merge
当再回到此分支时,发现暂存区是空的!需要把之前stash的内容恢复一下
$ git stash apply // 恢复后,stash内容并不删除,需要用git stash drop来删除
$ git stash pop // 恢复的同时把stash内容也删了
stash的另一种使用场景:当当前分支代码没有commit时,是无法pull代码下来,这时需要先stash
当在不同的分支,对同一个文件的同一个位置进行了修改,各自commit之后merge时:
这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突。
zhangfengqi@ED63038F43AD14D /D/zfengqi/github/Spoon-Knife (master)
$ git merge branch222
Auto-merging styles.css
CONFLICT (content): Merge conflict in styles.css
Automatic merge failed; fix conflicts and then commit the result.
这时候分支状态就会变成
zhangfengqi@ED63038F43AD14D /D/zfengqi/github/Spoon-Knife (master|MERGING)
手动解决冲突:打开发生冲突的文件,保留最终要的部分
Git用<<<<<<<
,=======
,>>>>>>>
标记出不同分支的内容
修改后,再次add & commit
$ git log --graph //可以看到分支合并图。
//pwd用于显示当前目录
$ pwd
/Users/michael/learngit
//cat
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes.
http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
var gitalk = new Gitalk({ clientID: '82f3fb6574634b43d203', clientSecret: '5790d9fdbfe9340d29810b694b3b2070a9a3b492', repo: 'zfengqi.github.io', owner: 'zfengqi', admin: ['zfengqi'], distractionFreeMode: true, id: window.location.pathname, }); gitalk.render('gitalk-container');