Uninote
Uninote
用户根目录
每日点滴

<!DOCTYPE html> <html><head><meta http-equiv='Content-Type' content='text/html; charset=utf8'><title>git basic</title> <script> var g_resRoot = '../../../__res/'; var g_json_outline = '{"children":[{"children":[{"children":[],"level":2,"lvNumber":"1.1","text":"working directory/working tree/工作空间"},{"children":[],"level":2,"lvNumber":"1.2","text":"repository 仓库"},{"children":[],"level":2,"lvNumber":"1.3","text":"index/stage area"},{"children":[],"level":2,"lvNumber":"1.4","text":"local & remote"}],"level":1,"lvNumber":"1","text":"基本概念"},{"children":[],"level":1,"lvNumber":"2","text":"git rebase"},{"children":[],"level":1,"lvNumber":"3","text":"权限控制"},{"children":[],"level":1,"lvNumber":"4","text":"tortoisegit 乌龟"}],"level":0,"lvNumber":"","text":"git basic"}'; </script> <link rel='stylesheet' type='text/css' href='../../../__res/common.css'><style>.s0{color:#000000;} .s1{color:#0000ff;} .s2{color:#c80000;} .s3{color:#000000;} .s4{color:#000000;} .s5{color:#c80000;} .s6{color:#0000ff;} .s7{color:#000000;} </style> </head><body> <script src='../../../__res/util.js'></script><div id='outline'> <li><a href='#ol_0' style='font-weight:bold; font-size:22px'>git basic</a></li> <li> <a href='#ol_1' >基本概念</a></li> <li> <a href='#ol_2' >working directory/working tree/工作空间</a></li> <li> <a href='#ol_3' >repository 仓库</a></li> <li> <a href='#ol_4' >index/stage area</a></li> <li> <a href='#ol_5' >local & remote</a></li> <li> <a href='#ol_6' >git rebase</a></li> <li> <a href='#ol_7' >权限控制</a></li> <li> <a href='#ol_8' >tortoisegit 乌龟</a></li> </div>

<pre id='ol_0' class='title'>git basic</pre> <pre><d class='s0'></d></pre> <h1 id='ol_1'>基本概念</h1> <pre><d class='s1'></d></pre> <h2 id='ol_2'>working directory/working tree/工作空间</h2> <pre><d class='s1'><img src='....\pic\b5f2e9a4bb11db058317a9863e8e89e3.jpg' /></d><d class='s0'></d></pre> <pre><d class='s0'>working-dir就是平时我们操作的地方,在这里我们进行添加、删除、修改文件等各种操作,以及merge/rebase/cherry-pick,都是在working-dir上进行的。所以在做这些操作之前,git都要求你working-dir没有任何修改。否则会报类似的错误:</d></pre> <pre><d class='s0'><img src='....\pic\bfd1dec47510d8e93d67369efb6658e0.jpg' /></d><d class='s0'></d></pre> <pre><d class='s0'></d></pre> <pre><d class='s0'>一点小提示:</d><d class='s2'>git的报错是非常准确的</d><d class='s0'>,耐心的研究它的报错,对你逐渐理解git大有帮助。而且一般读懂了它的报错,不用任何帮助都能自己解决问题。</d></pre> <pre><d class='s0'></d></pre> <pre><d class='s0'>另外,git在做任何操作时都会非常谨慎。也就是说,</d><d class='s2'>任何有可能造成你的文件丢失、修改被覆盖等等操作,git都会拒绝</d><d class='s0'>,除非你显示的加上诸如--force等参数。</d></pre> <pre><d class='s3'></d></pre> <t id='d05745a4-ab9c-4a0f-8e28-5a3af8be0586'> <pre class='tnd_head'>lv1= lv2= type=</pre> <h2 id='ol_3'>repository 仓库</h2> <pre><d class='s3'>代码仓库,后面简称repo(仓库)。每个git管理的项目,在根目录下都有一个.git(隐藏)文件夹,里面存储了所有的commit、branch、tag、index等信息。进入.git,可以看到它的目录结构如下:</d></pre> <pre><d class='s3'><img src='....\pic\1e5699fb259d56c75b1b945ef83fc7c8.jpg' /></d><d class='s0'></d></pre> <pre><d class='s0'>再看看它对应的server端的目录结构,基本是一样的:</d></pre> <pre><d class='s0'><img src='....\pic\798cff0fd9ab678a233ac814842618f4.jpg' /></d><d class='s0'></d></pre> <pre><d class='s1'></d></pre> <pre><d class='s3'>不光是这个测试项目,所有的git仓库的目录结构都是一致的;除了目录结构,最关键的数据的存储结构也是一样的。这也是git和svn类的版本管理软件最大的区别,git把所有的信息,在本地都存储了一份,服务器上有的,他都有(只要你成功的执行了pull/fetch操作)!</d></pre> </t> <pre><d class='s0'></d></pre> <h2 id='ol_4'>index/stage area</h2> <pre><d class='s3'>使用命令行,index的掌握是关键。每次commit,都是commit index的内容,而非working-dir的内容!!上节已经讲过,所有的index信息,都是存在.git本地仓库中的。</d></pre> <pre><d class='s3'></d></pre> <pre><d class='s3'>将某个a.txt添加到index:</d></pre> <pre><d class='s3'>git add path/to/a.txt</d></pre> <pre><d class='s3'>也可以添加某一类:</d></pre> <pre><d class='s3'>git add *.txt</d></pre> <pre><d class='s3'>或者添加全部:</d></pre> <pre><d class='s3'>git add *</d></pre> <pre><d class='s3'></d></pre> <pre><d class='s3'>从index撤销a.txt:</d></pre> <pre><d class='s3'>git reset -- path/to/a.txt</d></pre> <pre><d class='s3'>撤销所有:</d></pre> <pre><d class='s3'>git reset</d></pre> <pre><d class='s1'></d></pre> <pre><d class='s3'>另外,很多时候我们需要撤销working-dir里某个文件的修改(将其还原到上次提交之后的状态,比如一些临时修改需要丢弃),可以用:</d></pre> <pre><d class='s3'>git </d><d class='s2'>checkout</d><d class='s3'> -- path/to/file</d></pre> <pre><d class='s3'>如果本地所有修改你都要丢弃(</d><d class='s2'>注意,这条目录丢弃所有的本地修改,用它前请确认你是否需要这样做!!</d><d class='s3'>):</d></pre> <pre><d class='s3'>git reset --hard</d></pre> <pre><d class='s1'></d></pre> <h2 id='ol_5'>local & remote</h2> <pre><d class='s0'>在<a href='git.html#6d7871e6-47cc-4088-b5d9-c77e4142f3f5'>基础练习 </a>中,我们将git命令分为本地操作、远端(remote)操作两种。你执行一条命令,一定要清楚自己在干什么,很多人连是在操作本地仓库还是远端仓库都分不清楚。比如commit、push的区别,你清楚吗?因为中文的语境关系,有时可能会说你将修改</d><d class='s2'>提交</d><d class='s0'>以下,我看看,这里的提交,其实是指commit + push。但commit翻译成中文就是</d><d class='s2'>提交</d><d class='s0'>。。</d></pre> <pre><d class='s4'></d></pre> <pre><d class='s4'>另外需要注意的是,在解决冲突时,有的第三方工具,比如<a href='git.html#fcd334e2-7100-49e0-8ec7-c30c6574b29c'>beyond comparer </a></d><d class='s0'>会自动生成三个文件,BASE、LOCAL、REMOTE,这里的local/remote是另外的意思,不要误以为是在和remote(服务器)上的代码进行合并!</d></pre> <pre><d class='s4'></d></pre> <pre><d class='s4'>local操作操作的对象是working-dir & .git。也就是说,commit、merge、rebase等等这些操作,都只是在操作本地的git仓库的,和remote上的仓库没有半毛钱关系。本地操作不需要、也</d><d class='s5'>不可能</d><d class='s4'>有任何的<a href='git_basic.html#ac02fbd8-6753-4dec-aab4-e9a7a2249f66'>权限控制 </a></d><d class='s4'>。</d></pre> <pre><d class='s0'></d></pre> <pre><d class='s3'>所以几乎所有的操作,我们都是在操作本地仓库。除了clone/pull/fetch/push这几个命令之外(一些很不常用的,如ls-remote不讨论)。remote操作相对来说就很简单了,无非就是拉取(pull、fetch)和推送(push)。只不过因为涉及到多人同时操作,需要有一定的机制来保证不会产生相互间把对方的工作给覆盖掉了。其实思路有很简单,比如A、B两人先后往server上push同一个分支,当B再推送时,如果B的commits里面不包含A的commits,server就会拒绝这次推送。当然也可以强制覆盖,具体可参见git push的--force/--force-with-lease参数。可以push的情况,在git中叫做fast-forward(快进)。</d></pre> <pre><d class='s3'></d></pre> <pre><d class='s3'>这种设计有很多优势:</d></pre> <pre><d class='s3'>1、几乎所有的操作我们都是在操作本地仓库,对于本地仓库,我们拥有至高无上的权限,没有任何约束,你甚至可以完全删除working-dir和.git目录(当然,后果自负)。你可以保存任意多的临时代码、分支、tag,而且不用担心网络中断或者网速过慢导致无法工作!</d></pre> <pre><d class='s3'>2、working-dir与本地仓库间关注的是代码管理问题;本地仓库与remote仓库只关注数据传输问题,并不会涉及到任何的代码合并等问题。这是一种非常好的解耦设计。</d></pre> <pre><d class='s3'>3、本地仓库和remote仓库地位完全是对等的。体现在:</d></pre> <pre><d class='s3'> a) 目录结构、数据存储格式是一致的(<a href='git_basic.html#d05745a4-ab9c-4a0f-8e28-5a3af8be0586'>repository 仓库 </a></d><d class='s0'>)</d><d class='s3'></d></pre> <pre><d class='s3'> b) 一个仓库,即可以做server,也可以做client。比如我们可以直接clone一个本地仓库:</d></pre> <pre><d class='s3'><img src='....\pic\f409b04f5931429f7ab1d2412d22c887.jpg' /></d><d class='s3'></d></pre> <pre><d class='s3'>做完修改还可以push:</d></pre> <pre><d class='s3'><img src='....\pic\a16de8c9603c20ee5d9a0888a4457a93.jpg' /></d><d class='s3'></d></pre> <pre><d class='s3'>但是如果你要推送到master分支会报错(因为u1的当前分支是master):</d></pre> <pre><d class='s3'><img src='....\pic\bef3ab36791a3dc2b50c9d5f498d0777.jpg' /></d><d class='s3'></d></pre> <pre><d class='s3'> c) 仓库间仅存在数据传送的关系,是及其松耦合的。从serverA上clone的commits,可以push到serverB上;反之亦然。也就是说,一个本地仓库可以对应对个远端仓库,并可与任意一个仓库进行数据交互。即使这些remote仓库对应的是完全不相关的项目!</d></pre> <pre><d class='s3'></d></pre> <pre><d class='s3'>具体可以参见git remote命令的<a href='https://kernel.org/pub/software/scm/git/docs/git-remote.html'>官方文档</a>。</d></pre> <pre><d class='s3'></d></pre> <h1 id='ol_6'>git rebase</h1> <pre><d class='s3'>rebase/merge分别什么时候使用:同一个分支的代码在归并时使用rebase,其他情况使用merge。</d></pre> <pre><d class='s0'>比如,你当前在master分支,做了修改并commit,之后拉取了server,发现server的master分支有更新,此时就要用rebase。</d></pre> <pre><d class='s0'></d></pre> <t id='ac02fbd8-6753-4dec-aab4-e9a7a2249f66'> <pre class='tnd_head'>lv1= lv2= type=</pre> <h1 id='ol_7'>权限控制</h1> <pre><d class='s4'>为了避免服务器上的仓库被人有意无意的破坏,或者仓库的内容是私密的,不想让其他不相关的人看见,一般情况下管理员会给需要访问的人员一个RSA的私钥文件,拿到以后放到用户主目录下的.ssh文件夹下,并重命名为id_rsa。如果你用的是乌龟,需要将其转换为ppk格式。可以参考<a href='http://www.wojilu.com/space/wormbbs/blog3075/post/411'>这里</a>。</d><d class='s0'></d></pre> </t> <pre><d class='s6'></d></pre> <h1 id='ol_8'>tortoisegit 乌龟</h1> <pre><d class='s7'>乌龟在进行一些复杂操作时还是很有优势的。学习乌龟,首先要能看懂乌龟的历史图。</d></pre> <pre><d class='s7'><img src='....\pic\5a1fad9b9c1a402b554eab308d81ee8e.jpg' /></d><d class='s0'></d></pre> </body></html>

git

learn

点赞(0) 阅读(57) 举报
目录
标题