移动SVN上文件夹,怎么保留代码记录?

android开发中,SVN使用来共享代码,实现多人协同办公,一般公司都是使用这个工具来共享代码和提交代码吗?

在我们的认知范围Git和SVN都是对于代码托管的工具,那么这两者又有什么不同呢?

Git是世界上先进的「分布式的版本控制系统」,而SVN「集中式的版本控制系统」,SVN对于版本的管理集中于中央服务器中,而Git对于版本的管理可以在本地。

SVN管理的模式从SVN服务器中拉取代码,然后开始自己的开发,开发完后再向SVN服务器提交代码,所以集中式的版本管理,需要联网才能进行,一旦没网就没办法向SVN服务器提交代码。

而Git是分布式的版本管理,每个开发者的本地都会有完整的版本库,不需要来联网,也能进行版本的管理和代码的提交,每个开发者都可以再本地进行提交代码、查看版本、切换分支等操作。

所以相对于SVN来说Git的存储也会相对比较占用空间,但是以空间换来了Git对版本管理的高效,不得不说是一种高明的策略。

Git Bash Here就是我们用来敲命令的窗口,打开它就可以敲关于Git的命令进行进行操作。

Windows的Git下载地址:,在这里下载最新版的进行安装即可。

下面我们来说一下Git再Linux的安装过程,要在安装Git其实也非常简单,可以直接使用yum源进行安装,一句命令就搞定了:

安装完Git后就开始对Git进行配置操作,配置自己用户名和Email,配置的命令如下:

配置完信息后,就可以「创建目录,并且初始化自己的本地仓库」了:

我这里已经初始化过了,初始化后会默认在主干上(master),这里为了测试各种Git的各种命令使用本地的Git仓库于github进行关联。

本地仓库与Github关联

执行git clone就会生成一份副本,在本地仓库和工作区都会同步副本,具体的原理图如下所示:

从上面的图中我们可以到,代码可以在不同level之间移动,高level到低level,或者逆向低level到高level,也可以跨level之间移动。

Git中代码从低level到高leve的移动主要依靠以下命令:

  • git add .:文件添加进暂存区。
  • git commit -m "提交信息":文件添加进本地仓库,-m参数改为-am可以直接推向本地仓库。
  • git push:文件推向远程仓库。

运行git commit -a相当于运行git add把所有文件加入暂存区,然后再运行git commit把文件提交本地仓库。

那么从高level向低level移动代码的命令如下:

  • git pull:从远程仓库拉取代码到本地。
  • git reset --files:用本地仓库覆盖暂存区中修改,也就是覆盖最后一次git add的内容。
  • git checkout --files:把文件从暂存区复制到工作区,用于放弃本地的修改。

下面我用自己本地与github的操作测试上面的命令,加深对上面的命令的理解和使用,当我在本地新建一个github仓库中没有的文件:

可以看到文件的显示Untracked files:未被追踪的文件,「表示该文件未被git追踪管理」

新添加的文件可以通过「git add添加到在暂存区」「这样文件就能够被git进行追踪」,此时再使用git status查看文件时,就可以看到两个文件已经是以new file的形式进行显示:

若是你想撤销提交到暂存区的内容,使用git reset,可以撤销向暂存区新添加的文件:

也可以在使用命令:git reset --hard HEAD^,表示回退上一个版本,「在Git中HEAD表示当前版本,HEAD^表示上一个版本」,若是有多个版本,这样表示就不方便了,可以使用HEAD~10,表示版本的次数。

commit的本质就是:「每次Git都会用暂存区的文件创建一个新的提交,把当前的分支指向新的提交节点,这样就完成了一次新的提交」

若是HEAD指针指向的是bran分支,那么新的节点就会成为jh509的子节点,并且形成新的分支:

当你再次检查你的代码的时候就会回到了id为5567a版本,在Git的版本回退原理中,Git的内部有一个指当当前版本的HEAD指针,只要从当前版本指回去就行了,所以Git版本的回退是特别快的,只需要移动指针,实现的原理图如下所示:

丢弃工作区的修改使用:git checkout -- file命令,这条命令中的--files是不能漏的,若是只是git checkout就表示切换另一条分支的命令了。

在我的本地我直接修改:README.md文件,然后使用git status进行查看,他表示文件处于modified状态:

此时的README.md文件是还没有被添加进暂存区的,可以直接使用以下命令,撤销掉工作区的修改:

若是已经添加到暂存区了,就是用以下的命令进行回撤:

上面也演示了git reset命令,它既可以回退版本,又可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。

当你提交了修改后,可以使用git diff查看两次提交之间的变动,它的本质就是「任意比较两个仓库之间的差异」

在工作区直接使用rm fileName,这个操作和linux的命令一样,若是文件已经提交版本库,从版本库中删除文件可以使用git rm命令进行删除,然后提交:

若是删除错了,可以使用git checkout -- README.md进行恢复,其原理就是使用版本库的文件替换工作区的文件。

在团队中集体使用Git的时候,每个人都提交自己的代码最后合并到主干,总有会push失败的时候,因为push的本质:「就是用你本地仓库的commit记录去覆盖远程仓库的commit记录」

但是别人提交了一些代码,而你本地并没有这些代码,这样代码就会被覆盖,导致别人的commit的记录就不存在,这个是绝对不允许的。

所以,每次push的时候Git就会检查,若是存在这种情况就是push失败,只要先git pull一下,将本地仓库与远程仓库先合并一下,最后push就可以成功了,若是文件中已经存在在冲突代码,只要打开文件重新解决一下冲突即可。

Git中比较最重要的一点就是分支的概念,有了分支就有了合并和衍合的操作,「合并」「衍合」能够「有效的对代码版本的管理」

Git的初始化中有一条默认的主分支叫做master,每一次的提交都会串成一条时间线,这就是一条分支,当前分支由HEAD指针指向:

当每次发生代码提交的时候,当前指向就会向前形成一个新的版本,假如再创建一个新的分支bran,并且当前的提交指向新的分支,这样新的分支随着时间的推移就会形成许多版本:

当新分支开发完后,提交仓库,并合并到主干master,最后删除bran分支,这样就完成了一次个人的开发:

所以,假如主分支上只建立一条分支的话,分支的合并是非常快速的,只需要移动master分支到当前提交,然后将HEAD指针指向master,最后删除bran分支就完成了。

但是,事实上并不是这样的,在一个多人协作的开发团队中,往往每个人都会建立自己的分支,有自己的提交,最后合并到主干,当自己提交的时候,远程仓库代码就会存在自己本地仓库并未有的代码,这样就会导致push失败。

例如:程序员Tom和Jerry同时迁出代码,他们的初始代码分支都如下图所示:

当Tom开发自己的业务模块,提交代码并且合并到主干后,远程主干分支如下图所示:

「远程仓库master已经不再指向gs234,而是新生成了一个版本dfd453,作为当前指向的版本」

与此同时,Jerry的本地也同时开发完自己的模块后,分支如下图所示:

在Jerry的本地环境中,他的「本地仓库master还是指向gs234」,Jerry在自己新建立的一个分支bran中进行开发,开发完后合并分支,最后master就会指向ed489

当Jerry再次提交代码,Git就会检查远程仓库与Jerry的本地仓库,进行对比后,发现远程仓库存在Jerry的本地仓库不存在的代码,就需要Jerry将远程仓库执行git pull后,自行解决冲突。

上面说了分支基本原理,已经管理分支出现的问题,下面我们就来一步一步的深入操作分支的基本命令。

新建分支的实质:「就是新建立一个引用,指向当前提交,master就好比一个引用」;切换分支的实质:就是将HEAD由指向原来的引用,重新指向要切换的分支的引用上:

当然上面创建分支并且合并分支的两条命令可以合并成一条命令:git checkout -b <分支名字>

当切换分之后,每次commit提交代码时HEAD指针就会跟随着新的bran分支移动,形成bran分支上的每一个版本:

假如,在新的bran分支上开发到某一个版本,再次切换回master分支进行开发就会形成分叉:

当分支创建好了,你可以通过:git branch,来查看自己本地的分支情况:

分支前面带有*号的表示当前的分支,查看分之后,你就可以很清楚的知道自己要checkout哪条分支了。

开发玩自己模块后,后面就会在自己本地进行合并分支,合并分支的命令:git merge <分支名字>,它表示「合并指定的分支到当前分支」,比如:当前分支为master,执行:git merge bran,表示合并bran分支到当前master分支上。

分支合并也会有失败的情况,当你的两条分支都修改的相同的文件,这时候Git就无法判断你要保留哪一个修改,就会出现merge冲突。

例如:我先在master分支修改README.md文件,然后提交本地仓库:

然后切换回分支dev,再次修改README.md文件,再次提交

最后进行合并分支,此时在你两次修改的README.md文件中就会出现两次修改的冲突代码:

因为你两次修改同一文件的操作,合并后Git并不知道你要保留哪一次的操作,所以它就会将这个决定交给你自己决定,它只告诉你文件中哪里的代码冲突了,具体怎么改就由你自己去弄。

最后是删除自己新建的分支,通过:git branch -d <分支名字>,进行删除分支,假如分支删除不了,可以通过:git branch -D <分支名字>,强制删除分支:

Git中删除分支的实质:dev只是一个分支的引用,所以删除分支也就是删除这个引用,并不会删除任何conmit,所以删除操作也是非常高效的。

假如一条分支commit的引用被删除,那么这条分支的就没有任何引用指向,这样就会找不到这条分支,最后就会被Git回收机制回收。

在多人协作的团队下,你可能要随时查看远程仓库的情况,可以通过:git remote,进行查看,加上-v参数可以查看远程仓库的详细情况。

分支的推送到远程上一节已经提过,使用git push命令就可以进行分支的推送,命令后面加上分支的命令,表示具体推送哪条分支:

分支的拉取使用git pull命令,这条命令相当于以下两条命令:

但是一般实际工作中,都可能会直接使用git pull命令:

在合并分支的时候,Git会以快速合并的模式进行合并(Fast forward),但是这种模式删除分支后,会丢失分支的信息。

Git中还可以以「普通模式」进行合并,在原来git merge命令后面加上--no-ff参数即可,合并的命令如下:

在开发中,若是某一时刻你想把当前的改动临时进行存放起来,可以使用git stash命令,它表示将改动的文件存储到一个独立的存储区域,并不会被提交,当再次需要的时候可以随时取出来。

这里要注意的是:「git stash的是改动的文件,也就是被Git追踪的文件,新添加的文件并没有被Git追踪,所以git stash并不会stash」

git stash命令也可以加上save命令后面再加上备注信息,方便查看:

git stash成功后「本地的工作目录的代码会和本地仓库一样」git stash后可以通过git stash list命令查看之前stash的历史记录,当再次需要将改动的文件取出来时候,可以通过以下命令:

git stash pop表示「弹出第一个被stash的记录,并且该stash会从历史记录中删除」;也可以使用git stash apply命令「弹出stash,但是这条命令stash任然会保存在stash历史记录中」,你也可以通过:git stash drop命令来删除。

这一篇就只讲解了Git的分支原理以及Git的临时存取操作,限于篇幅,我们今天就到这里,我们下一期继续图解Git操作,我们下一期再见。

这一篇我们继续图解Git,上两篇原创图解了Git的基本操作,有兴趣的可以看一看[]和[]。

这一篇写完基本Git的操作就图解完了,如果想深入了解Git,这里可以推荐一些Git的硬核书籍:【精通Git】、【GitHub入门与实践】、【Git权威指南】、【Git版本控制管理】、【GitHub实践】。

这些都是一些关于Git的比较好的书籍,有兴趣的可以可看一看,网上也有很多电子书。闲话不多说,下面就开始我们的正题。

Git查看日志前面有提到过可以通过git log命令进行查看:

git log可以查看你「提交的时间、提交的作者、以及提交的id」都可以查到,如果你觉得查询的信息太多,可以加上参数--pretty=oneline,只会显示版本号和提交时的备注信息。

如果你想查最近的几条历史记录,可以通过加参数"-n"的形式制定查询几条记录,历史记录是「按照操作的时间」进行排序的:

还可以通过加参数" --graph",以图形化的形式展示历史记录,方便与查看历史记录与分支的关系:

还可以加参数"-p",可以查看每一个commit操作更改的文件的哪一行,加参数"-stat"查看哪些文件改动了,进行简要的统计。更加详细的git log参数可以查看命令帮助。

Git查看历史记录的另一个命令是git reflog,它可以查看「所有分支的所有操作记录,包括已经删除的commit记录和reset记录」

分支管理中有「合并」「衍合」操作,合并操作在在第二年篇的分支章节已经详细讲解过了,就来讲解一下衍合操作:git rebase操作。

假如有两位开发人员Tom和Jerry,Tom和Jerry都把远程的master分支签出到本地,此时当前的Tom和Jerry本地都是只有一条master分支:

此时Tom本地仓库和远程仓库的分支保持一致,分支如下图所示:

Tom在自己的分支branch上开发自己的模块,假如开发期间Tom进行了「两次」的提交,最后Tom本地的分支形成如下所示:

也可以通过git log查看两次提交的记录:

若是,此时Tom开发人员准备把自己的branch的分支推向远程仓库,但是,Jerry在此之前已经在master提交了自己的开发代码,所以master分支相比之前记录,已经向前推进了一个版本。

所以此时Tom想提交,必须先更新一下自己的本地分支:

Tom中通过git log命令可以查看到Jerry的提交记录情况,说明此时分支已经与远程仓库同步:

此时Tom更新分之后,本地的分支情况如下所致,相比原来master指向c1,现在向前推进了一个版本指向c4:

此时,Tom必须重新合并分支进行提交,把branch的代码合并到master分支上,现在Tom可以有两种方式:

(1)若是使用第一种方法直接在master分支上执行git merge命令,「Git会把master分支上最新的提交c4的内容和branch分支上最新的提交c3 合并后生成一个新的提交点c5」

上面实在没有冲突的前提下,若是有冲突,则解决冲突:

此时就完成了master和branch分支的合并。

(2)若是使用第二个方法,先master也需要拉取到最新版本,然后是切换到branch分支,这个也就是要切换到rebase的分支,这里指的是branch分支。

通过测试可以发现,原来branch分支上重新commit的节点c4在rebase到master分之后hash发生了改变,并且提交的内容被复制保留,从而使得master分支整个呈现线性的commit记录,而不是直接git merge后的分叉记录。

注意:「一般不是在branch进行rebase主分支master的提交,因为会导致master的新提交在本地丢失,这样有可能会导致本地仓库与远程仓库发生冲突,从而无法push操作」

「总结」「git merge会将两个分支的最新提交点进行一次合并,形成一个新的提交点,最终形成树状的提交记录」,但是有些人并不是喜欢merge,觉得merge之后出现的分叉会难以管理,那么可以选择rebase操作来替代merge。

「git rebase操作是将要rebase的分支最新提交点作为新的基础点,将当前执行git rebase master的分支的新commit点重新生成commit hash值,rebase完后再次切换到另一条分支进行合并,就可以保证线性的commit的记录」

「最后只选择merge还是rebase取决于个人和时机情况,假如你想提交记录呈现线性整洁那么选择rebase,否则选择merge,实际情况也有可能是这样的,每个人本地开发,可能会提交非常的多次,有些提交可能是修一些简单的bug,那么最后的提交只想做一次完整、正确的提交,那么也可以使用rebase。」

Git中使用的标签有两种类型:「轻量级的(lightweight)和含附注的(annotated)」。轻量级标签只需在git tag后加上标签的名字,就可以添加标签。

标签管理作为开发人员可能很少使用,可以作为了解,「tag是针对Git中某一时间某一版本打上标签」,tag的使用命令也是非常的简单。

新建一个标签,默认是在HEAD新建,可以指定commit id新建,具体命令如下所示:

删除标签若是标签没有推向远程仓库,直接使用以下命令删除:

若是标签已经推向远程仓库,先删除本地,再删除远程仓库的标签:

git tag的方式是查看所有的标签,git show <标签名>的方式是查看每个特定的标签

推送标签也是分两种情况,一种是指定标签的推送,另一种是推送所有标签。

代码错误提交了怎么办,重新再一次提交一个版本呗,这个可能是很多人的解决方案,当然Git也是有提供自己的解决方案的命令。

第一种就是再次将修改文件然后git add .到暂存区,最后git commit --amend提交修改 ,它的原理图如下所示:

这种方法只能修改当前HEAD,也就是最新的提交,那么要修改是倒数第二个或者倒数第三个的提交呢?

这时候就要使用rebase -i「交互式rebase」)进行操作了,这个命令是指定commit链中哪一个commit需要修改。

若是想直接丢弃最新的commit的修改,则直接使用命令:git reset --hard HEAD^。他表示当前commit往前移动一次。

好了图解Git操作基本讲解完了,其他的一些细节操作基本都是在基本操作的基础上加参数,详细的参数大家可以参考官网或者相关的书籍。

在公司的实际应用这三篇图解Git操作基本可以应付了,上面说的交互式操作,基本没用过,只做大致的了解,但是之前在面试华为的时候有被问到Git的交互操作。

最后,帮助粉丝Git的进阶,给粉丝送福利,送出两本书 「《Git入门到精通》」,获取的形式本文的「留言区前两名的粉丝」可以获得,活动时间到10/8 18:00 -10/10 12:00。

捐赠:支付宝 yangyangwithgnu@ 上搜索 vim ide 关键字后第一匹配项便是本文,洋人浏览到本文的次数非常多,常常收到要求同步发表英文版的邮件,但是,你知道,这 80+ 页的中文已经耗费我大量业余时间,所以,如果可能,希望有精力的朋友可以将其翻译为英文,感谢!

  • 讨论:任何意见建议移步



  • 译:yangyangwithgnu@ 有丰富的插件资源,任何你想得到的功能,如果 vim 无法直接支持,那一般都有对应的插件为你服务,有需求时可以去逛逛。

    clang + 后端 LLVM(后简称 LLVM/clang)就是一款可替代 GCC 的优秀编译器。相较 GCC,LLVM/clang 有众多优势,尤其以下几点: 错误信息可读性强。能指出哪行、哪列有错误,并且用波浪线突显出来;另外,尽可能给出修改建议(比如提示你是否拼写错误);最重要的是对 C++ 模板相关语法错误提示非常友好;(注,GCC 与我同在。发布在

嗷呼,经过以上调教,你的 vim 已经成为非常舒适的 C/C++ 开发环境呢。等等,重装系统后又得折腾一次?不怕,除了 clang 等等几个需要源码安装的工具外,基本上,vim 的插件和相关配置文件你可以提前备份好,装完系统后恢复到对应目录中即可,丝毫不费脑力。

2011 年 9 月我写了篇《拼装的艺术:vim 之 IDE 进化实录》,原计划近期(2014-09)更新下智能补全部分,后来越改越发觉原版问题太多,加之各插件推陈出新、自己对 vim 的认识加深,索性完全重新。期间,与很多朋友有过交流,有三类问题探讨得最频繁,我的观点简要阐述如下,后续不再欢迎、理会、回复相关问题:

  • 为何不用 Code::Blocks 这类一站式 IDE?每个人的做事的出发点、性格观念千差万别,我不想拿 linux kernel 是 linus torvalds 用 microemacs(emacs 变种)开发的来说事儿,就我而言,迷恋 vim 的高效编辑能力、无限扩充能力,这是其他编辑器无法超越的。此外,我享受的是过程,不是结果!
  • 哪个是最适合编码的编辑器?linux 上存在两种编辑器:神之编辑器 emacs,编辑器之神 vim。关于 emacs 与 vim 孰轻谁重之争已是世纪话题,我无意参与其中,在我眼里,它们流淌着自由的血液、继承着创新的基因,作为顶级编辑器,二者在这个领域都作到了极致,让世人重新认识了编辑的本质 —— 用命令规则而非字字键入 —— 去完成编辑任务。emacs,伪装成编辑器的操作系统,太杂、太重,我更喜欢专注于编辑的 vim。
  • 怎样的 IDE 才算好?对于初入开发的人员而言,Code::Blocks 是最易上手的选择;对于我这类喜欢折腾、追求效率、愿意用脑力换体力的人来说,vim 搭配各类插件是好的 IDE;对于 Donald Knuth 这等宗师,他们站在整个系统的层面,bash 加上几个命令行工具也是某种意义上的 IDE。所以,只要你能得心应手地完成软件开发任务,又察觉不到工具的存在,那这就是最适合你的 IDE。

末了,写作的过程,是知识体系完整重构的过程,理清了思路、加深了记忆。如果它再能引发你的一点思绪,或许,这就是价值!

我要回帖

更多关于 如何清空文件夹里的文件 的文章

 

随机推荐