git和svn

git教程
SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作。
Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。

git学习大全

git clone 地址 //克隆远程仓库代码

git config --global --list //查看本地全局git配置信息

git config --local --list  //查看本地局部git配置信息

git config --global user.name 'zhangliang'  //全局配置名字

git config --global user.email 'htlzl123@163.com' //全局配置邮箱

以上同理 --local //局部配置

git checkout -b feature/fund  //生成本地feature/fund ,并切换到该分支

git checkout dev (切换到本地dev分支)

git diff 查看你所修改的文件的具体信息   q键退出命令行

git  restore  文件名(或者文件夹)  将本地所修改的文件回撤到修改前(配合 git status用)

本地修改配置文件,又修改了想要提交的文件,这时候把需要提交的文件先,git add 和 git commit 提交到本地版本库中,然后执行git stash 去存储不想提交的配置文件,然后执行提交或者合并操作,否则提交代码会报错说本地分支较远程分支behind,等push之后就可以使用git stash apply 去恢复

git stash save "save message"  : 执行存储时,添加备注,方便查找,只有git stash 也要可以的,但查找时不方便识别。

git stash list  :查看stash了哪些存储

git stash show :显示做了哪些改动,默认show第一个存储,如果要显示其他存贮,后面加stash@{$num},比如第二个 git stash show stash@{1}

git stash show -p : 显示第一个存储的改动,如果想显示其他存存储,命令:git stash show  stash@{$num}  -p ,比如第二个:git stash show  stash@{1}  -p

git stash apply :应用某个存储,但不会把存储从存储列表中删除,默认使用第一个存储,即stash@{0},如果要使用其他个,git stash apply stash@{$num} , 比如第二个:git stash apply stash@{1} 

git stash pop :命令恢复之前缓存的工作目录,将缓存堆栈中的对应stash删除,并将对应修改应用到当前的工作目录下,默认为第一个stash,即stash@{0},如果要应用并删除其他stash,命令:git stash pop stash@{$num} ,比如应用并删除第二个:git stash pop stash@{1}

git stash drop stash@{$num} :丢弃stash@{$num}存储,从列表中删除这个存储

git stash clear :删除所有缓存的stash

git add .  跟踪所有更改的文件

git restore --staged 文件名(或者文件夹)  取消对文件的跟踪,但保留文件的更改

git commit -m '个股资讯修改'      把跟踪的文件提交到本地版本库

git commit -a -m 'change one file'      git add 和 git commit 二合一

git reset --soft HEAD^    回撤到本次commit之前,注意仓库首次commit信息不能用他撤回,会报错的

git reset --head HEAD^  回撤到上一个commit版本,及把本次commit的修改全部废除了

 git reset --hard b7d4d05  撤回到某个版本(你本次修改并commit的记录会废除)

git reset --soft b7d4d05  撤回到某个版本(暂存本地修改,即add了一下,但是没有commit)

git pull origin(远程主机名) feature/fund(本地分支):feature/fund(远程分支)

如果本地分支和远程分支名字一样  则可以简写为下面 =》

git pull origin feature/fund

git pull   =   git fetch(更新远程仓库的代码到本地仓库)  +  git merge(将内容合并到当前分支)

git fetch origin feature/fund 把最新远程feature/fund仓库的代码到本地仓库

git merge origin/feature/fund   将远程feature/fund仓库的代码合并到当前分支

如果存在冲突 解决冲突后需要重新提交      git add +  git commit

查看冲突 git diff ,会显示到预期版本(线上版本)的操作,加减符号展示(例如 减号代码线上没有的,而本地有)
 
git merge --abort   回撤到冲突之前的代码

git push origin(远程主机名) feature/fund(本地分支):feature/fund(远程分支)
代码提交线上 ,可以简写为  git push origin feature/fund

git status 查看当前状态  并提示接下来可以要操作的git指令信息

git status -s  简约查看当前状态信息

git log 查看日志  

git log --oneline 简约查看日志方式

git log --oneline --graph  简约图形方式查看日志

git log origin/master..HEAD 查看即将推送到远端的内容

git log dev1..dev2   查看dev2有,而dev1没有的内容
git log ^dev1 dev2  查看dev2有,而dev1没有的内容
git log dev2 --not dev1  查看dev2有,而dev1没有的内容

git log dev2...dev1 --left-right   dev1或dev2不同时存在的内容

git log --stat  查看所有提交修改过的文件

git log --pretty=format:"%h - %an,%ar : %s"  //其中一条为a2c62c2 - zanlan123,25 hours ago : 修改bug了
作者是最初开展工作的人,而提交者则是最后将工作成果提交的人。所以
格式选项 输出格式的描述
%H 提交对象的散列值
%h 提交对象的简短散列值
%T 树对象的散列值
%t 树对象的简短散列值
%P 父对象的散列值
%p 父对象的简短散列值
%an 作者的名字
%ae 作者的电子邮箱
%ad 创作日期(可使-date=选定日期格式)
%ar 相对于当前日期的创作日期
%cn 提交者的名字
%ce 提交者的电子邮箱地址
%cd 提交日期
%cr 相当于当前日期的提交日期
%s 提交信息的主题
git log的常见选项
选项 描述
-p 按补丁格式显示每个提交引入的更改
--stat 显示每个提交中被更改的文件的统计信息
--shortstat 只显示上述--stat输出中包含“已更改/新增/删除”行的统计信息
--name-only 在每个提交信息后显示被更改的文件列表
--abbrev-commit 只显示完整的SHA-1 40--relative-date 显示相对日期(例如两周前),而不是完整日期
--graph 在提交历史旁边显示ASCII图表,用于展示分支和合并的历史信息
--pretty 用一种可选格式显示提交。选项有oneline、short 、full、 fuller、 format(用于指定自定义格式)

git log --oneline --graph  --decorate  简约图形方式查看日志,并包含commit信息

git log -Sstr     str是添加或者删除特殊的字段,查找最近操作str的文件commit提交

git log输出范围的选项

选项 描述
--since,--after 只输出指定日期之后的提交
--until,--before 只输出指定日期之前的提交
--author 只输出作者与指定字符串匹配的提交
--committer 只输出提交者与指定字符串匹配的提交
--grep 只输出提交信息包含指定字符串的提交
-S 只输出包含添加或删除指定字符串的更改的提交

git help config  弹出config网页说明

git help add   弹出add   网页说明

git help commit  弹出commit  网页说明

git help 命令   对应获取该命令的使用方法git

git add  (命令) -h   如果只需要一部分手册 可以使用这个

git log --committer=zanlan   --oneline 查看zanlan用户的commit记录

git log -p -2  生成两次commit的补丁(patch)

git log -1 查看最近一次提交信息

git diff 70b2c26 c256e22  比较两个commit更改  显示从70b2c26 到 c256e22  的过程

git show 70b2c26    查看70b2c26 的更改

git show -1 查看上一次提交了的更改

git config --global alias.ci commit   当要输入 git commit 时,只需要输入 git ci。

git config --unset alias.ci   删除别名

git commit --amend 沿用上一次commit

git remote -v 查看仓库

git remote add origin2  git@github.com:zanlan/twokey.git  添加远程仓库

git remote remove origin2  删除远程仓库

git remote rename origin2 origin3  重命名

git remote show origin3 查看某个仓库信息

git remote rm origin3  删除远程仓库origin3

git branch  查看本地分支

git branch -v  查看每个分支的最后一次提交

git branch -a 查看远程分支 

git branch --merged  以过滤这个列表中已经合并

git branch --no-merged  尚未合并到当前分支的分支

git branch -d dev 删除dev本地分支

git branch -D dev 强制删除dev本地分支

git push origin -d dev   删除远程dev分支

git diff --staged       如果被修改的文件暂存了,需要查看修改信息,需要加--staged
git diff --ours	         要在合并前比较结果与在你的分支上的内容,换一句话说,看看合并引入了什么
git diff --theirs  	 如果我们想要查看合并的结果与他们那边有什么不同,
git diff --base 	 来查看文件在两边是如何改动的。

git rebase master     以master为基地 开始变基

git rebase --continue   继续变基

git rebase --abort   取消变基

--------------------------------------------------------------------------------



由master主分支切换两个分支  hotfix   iss53
如果iss53 分支需要拉取 hotfix 所做的修改,可以 git merge master 将 master 分支合并入 iss53 分支,
如果不需要可以等到 iss53 分支完成其使命,再将其合并回 master 分支。

git checkout master
git merge iss53
这和你之前合并 hotfix 分支的时候看起来有一点不一样。 在这种情况下,你的开发历史从一个更早的地方开始分叉开来(diverged)。 因为,master 分支所在提交并不是 iss53 分支所在提交的直接祖先,Git 不得不做一些额外的工作。 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4C5)以及这两个分支的公共祖先(C2),做一个简单的三方合并。




--------------------------------------------------------------------------------

 创建一个 .gitignore 的文件,列出要忽略的文件的模式。对于线上已有的文件修改,则本文件无效
例如线上已经有了4.js   .gitignore写了 *.js    并没有效果,它只会对本地新建的文件有作用
# 忽略所有的 .js 文件
*.js

# 但跟踪所有的 lib.js,即便你在前面忽略了 .js 文件
!lib.js

# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO

# 忽略任何目录下名为 build 的文件夹
build/

# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt

# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf

--------------------------------------------------------------------------------
一台电脑两套密匙,扮演两个用户,练习git命令
ssh-keygen -t rsa -C zanlan123@163.com
回车后 第一项输入 id_rsa_github

ssh-keygen -t rsa -C htlzl123@163.com
回车后 第一项输入 id_rsa_oschina

把生成的文件拷贝到.ssh文件夹下

git config --local --list 
git config --local user.name zanlan123
git config --local user.email zanlan123@163.com

.ssh 同级文件下新建config文件  放下下面内容
    Host github.com
    HostName github.com
    User github
    IdentityFile ~/.ssh/id_rsa_github   
     
    Host git.oschina.net
    HostName git.oschina.net
    User oschina
    IdentityFile ~/.ssh/id_rsa_oschina
把两个id_rsa_github.pub 和 id_rsa_oschina.pub 放入github


在本地新建两个文件  第一个文件新建readme.md 文件
输入11111111111
git init 
git config user.name 'zanlan'
git config user.email 'zanlan123@163.com'
会在.git 下的 config文件下看到设置信息
以后提交都会携带

另外一个文件同理

--------------------------------------------------------------------------------
常用命令
mkdir www 新建文件夹
touch 1.txt 新建文件
vim 1.txt  查看文件
mv 1.txt 2.txt 文件重命名
mv www wwww 文件夹重命名
mv 2.txt wwww/ 移动文件到文件夹
rm 2.txt   删除文件
rm -r www/  删除文件夹
rimraf www/删除文件夹  

--------------------------------------------------------------------------------

一个文件夹下开发不同的任务

git checkout -b feature/fund 

git checkout master  接下一个任务  切换到主分支 

git pull origin master   将代码更新一下

git checkout feature/nextrenwu

--------------------------------------------------------------------------------

有时候git add .    会报警告    arning: LF will be replaced by CRLF in

原因是需要提交的文件是在windows下生成的,windows中的换行符为 CRLF, 而在linux下的换行符为LF,所以在执行add . 时出现提示,解决办法

git config --global core.autocrlf false

--------------------------------------------------------------------------------

线上已有的文件  

git update-index --assume-unchanged  www/

git update-index --assume-unchanged 1111.md

git update-index --no-assume-unchanged 1111.md

git ls-files -v|grep '^h'   查看哪些没忽略了文件


.git/info/exclude   线上没有而本地新建的文件  类似/.gitignore

--------------------------------------------------------------------------------

3.6 Git 分支 - 变基
变基
在 Git 中整合来自不同分支的修改主要有两种方法:merge 以及 rebase。 在本节中我们将学习什么是“变基”,怎样使用“变基”,并将展示该操作的惊艳之处,以及指出在何种情况下你应避免使用它。
变基的基本操作
请回顾之前在 分支的合并 中的一个例子,你会看到开发任务分叉到两个不同分支,又各自提交了更新。

Figure 35. 分叉的提交历史
之前介绍过,整合分支最容易的方法是 merge 命令。 它会把两个分支的最新快照(C3C4)以及二者最近的共同祖先(C2)进行三方合并,合并的结果是生成一个新的快照(并提交)。

Figure 36. 通过合并操作来整合分叉的历史
其实,还有一种方法:你可以提取在 C4 中引入的补丁和修改,然后在 C3 的基础上应用一次。 在 Git 中,这种操作就叫做 变基(rebase)。 你可以使用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。
在这个例子中,你可以检出 experiment 分支,然后将它变基到 master 分支上:
$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command
它的原理是首先找到这两个分支(即当前分支 experiment、变基操作的目标基底分支 master) 的最近共同祖先 C2,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件, 然后将当前分支指向目标基底 C3, 最后以此将之前另存为临时文件的修改依序应用。 (译注:写明了 commit id,以便理解,下同)

Figure 37.C4 中的修改变基到 C3 上
现在回到 master 分支,进行一次快进合并。
$ git checkout master
$ git merge experiment

Figure 38. master 分支的快进合并
此时,C4' 指向的快照就和 the merge example 中 C5 指向的快照一模一样了。 这两种整合方法的最终结果没有任何区别,但是变基使得提交历史更加整洁。 你在查看一个经过变基的分支的历史记录时会发现,尽管实际的开发工作是并行的, 但它们看上去就像是串行的一样,提交历史是一条直线没有分叉。
一般我们这样做的目的是为了确保在向远程分支推送时能保持提交历史的整洁——例如向某个其他人维护的项目贡献代码时。 在这种情况下,你首先在自己的分支里进行开发,当开发完成时你需要先将你的代码变基到 origin/master 上,然后再向主项目提交修改。 这样的话,该项目的维护者就不再需要进行整合工作,只需要快进合并便可。
请注意,无论是通过变基,还是通过三方合并,整合的最终结果所指向的快照始终是一样的,只不过提交历史不同罢了。 变基是将一系列提交按照原有次序依次应用到另一分支上,而合并是把最终结果合在一起。
更有趣的变基例子
在对两个分支进行变基时,所生成的“重放”并不一定要在目标分支上应用,你也可以指定另外的一个分支进行应用。 就像 从一个主题分支里再分出一个主题分支的提交历史 中的例子那样。 你创建了一个主题分支 server,为服务端添加了一些功能,提交了 C3C4。 然后从 C3 上创建了主题分支 client,为客户端添加了一些功能,提交了 C8C9。 最后,你回到 server 分支,又提交了 C10。

Figure 39. 从一个主题分支里再分出一个主题分支的提交历史
假设你希望将 client 中的修改合并到主分支并发布,但暂时并不想合并 server 中的修改, 因为它们还需要经过更全面的测试。这时,你就可以使用 git rebase 命令的 --onto 选项, 选中在 client 分支里但不在 server 分支里的修改(即 C8C9),将它们在 master 分支上重放:
$ git rebase --onto master server client
以上命令的意思是:“取出 client 分支,找出它从 server 分支分歧之后的补丁, 然后把这些补丁在 master 分支上重放一遍,让 client 看起来像直接基于 master 修改一样”。这理解起来有一点复杂,不过效果非常酷。

Figure 40. 截取主题分支上的另一个主题分支,然后变基到其他分支
现在可以快进合并 master 分支了。(如图 快进合并 master 分支,使之包含来自 client 分支的修改):
$ git checkout master
$ git merge client

Figure 41. 快进合并 master 分支,使之包含来自 client 分支的修改
接下来你决定将 server 分支中的修改也整合进来。 使用 git rebase <basebranch> <topicbranch> 命令可以直接将主题分支 (即本例中的 server)变基到目标分支(即 master)上。 这样做能省去你先切换到 server 分支,再对其执行变基命令的多个步骤。
$ git rebase master server
如图 将 server 中的修改变基到 master 上 所示,server 中的代码被“续”到了 master 后面。

Figure 42. 将 server 中的修改变基到 master 上
然后就可以快进合并主分支 master 了:
$ git checkout master
$ git merge server
至此,client 和 server 分支中的修改都已经整合到主分支里了, 你可以删除这两个分支,最终提交历史会变成图 最终的提交历史 中的样子:
$ git branch -d client
$ git branch -d server

Figure 43. 最终的提交历史
变基的风险
呃,奇妙的变基也并非完美无缺,要用它得遵守一条准则:
如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。
如果你遵循这条金科玉律,就不会出差错。 否则,人民群众会仇恨你,你的朋友和家人也会嘲笑你,唾弃你。
变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。 如果你已经将提交推送至某个仓库,而其他人也已经从该仓库拉取提交并进行了后续工作,此时,如果你用 git rebase 命令重新整理了提交并再次推送,你的同伴因此将不得不再次将他们手头的工作与你的提交进行整合,如果接下来你还要拉取并整合他们修改过的提交,事情就会变得一团糟。
让我们来看一个在公开的仓库上执行变基操作所带来的问题。 假设你从一个中央服务器克隆然后在它的基础上进行了一些开发。 你的提交历史如图所示:

Figure 44. 克隆一个仓库,然后在它的基础上进行了一些开发
然后,某人又向中央服务器提交了一些修改,其中还包括一次合并。 你抓取了这些在远程分支上的修改,并将其合并到你本地的开发分支,然后你的提交历史就会变成这样:

Figure 45. 抓取别人的提交,合并到自己的开发分支
接下来,这个人又决定把合并操作回滚,改用变基;继而又用 git push --force 命令覆盖了服务器上的提交历史。 之后你从服务器抓取更新,会发现多出来一些新的提交。

Figure 46. 有人推送了经过变基的提交,并丢弃了你的本地开发所基于的一些提交
结果就是你们两人的处境都十分尴尬。 如果你执行 git pull 命令,你将合并来自两条提交历史的内容,生成一个新的合并提交,最终仓库会如图所示:

Figure 47. 你将相同的内容又合并了一次,生成了一个新的提交
此时如果你执行 git log 命令,你会发现有两个提交的作者、日期、日志居然是一样的,这会令人感到混乱。 此外,如果你将这一堆又推送到服务器上,你实际上是将那些已经被变基抛弃的提交又找了回来,这会令人感到更加混乱。 很明显对方并不想在提交历史中看到 C4C6,因为之前就是他把这两个提交通过变基丢弃的。
用变基解决变基
如果你 真的 遭遇了类似的处境,Git 还有一些高级魔法可以帮到你。 如果团队中的某人强制推送并覆盖了一些你所基于的提交,你需要做的就是检查你做了哪些修改,以及他们覆盖了哪些修改。
实际上,Git 除了对整个提交计算 SHA-1 校验和以外,也对本次提交所引入的修改计算了校验和——即 “patch-id”。
如果你拉取被覆盖过的更新并将你手头的工作基于此进行变基的话,一般情况下 Git 都能成功分辨出哪些是你的修改,并把它们应用到新分支上。
举个例子,如果遇到前面提到的 有人推送了经过变基的提交,并丢弃了你的本地开发所基于的一些提交 那种情境,如果我们不是执行合并,而是执行 git rebase teamone/master, Git 将会:
检查哪些提交是我们的分支上独有的(C2C3C4C6C7)
检查其中哪些提交不是合并操作的结果(C2C3C4)
检查哪些提交在对方覆盖更新时并没有被纳入目标分支(只有 C2C3,因为 C4 其实就是 C4')
把查到的这些提交应用在 teamone/master 上面
从而我们将得到与 你将相同的内容又合并了一次,生成了一个新的提交 中不同的结果,如图 在一个被变基然后强制推送的分支上再次执行变基 所示。

Figure 48. 在一个被变基然后强制推送的分支上再次执行变基
要想上述方案有效,还需要对方在变基时确保 C4' 和 C4 是几乎一样的。 否则变基操作将无法识别,并新建另一个类似 C4 的补丁(而这个补丁很可能无法整洁的整合入历史,因为补丁中的修改已经存在于某个地方了)。
在本例中另一种简单的方法是使用 git pull --rebase 命令而不是直接 git pull。 又或者你可以自己手动完成这个过程,先 git fetch,再 git rebase teamone/master。
如果你习惯使用 git pull ,同时又希望默认使用选项 --rebase,你可以执行这条语句 git config --global pull.rebase true 来更改 pull.rebase 的默认配置。
如果你只对不会离开你电脑的提交执行变基,那就不会有事。 如果你对已经推送过的提交执行变基,但别人没有基于它的提交,那么也不会有事。 如果你对已经推送至共用仓库的提交上执行变基命令,并因此丢失了一些别人的开发所基于的提交, 那你就有大麻烦了,你的同事也会因此鄙视你。
如果你或你的同事在某些情形下决意要这么做,请一定要通知每个人执行 git pull --rebase 命令,这样尽管不能避免伤痛,但能有所缓解。
变基 vs. 合并
至此,你已在实战中学习了变基和合并的用法,你一定会想问,到底哪种方式更好。 在回答这个问题之前,让我们退后一步,想讨论一下提交历史到底意味着什么。
有一种观点认为,仓库的提交历史即是 记录实际发生过什么。 它是针对历史的文档,本身就有价值,不能乱改。 从这个角度看来,改变提交历史是一种亵渎,你使用 谎言 掩盖了实际发生过的事情。 如果由合并产生的提交历史是一团糟怎么办? 既然事实就是如此,那么这些痕迹就应该被保留下来,让后人能够查阅。
另一种观点则正好相反,他们认为提交历史是 项目过程中发生的事。 没人会出版一本书的第一版草稿,软件维护手册也是需要反复修订才能方便使用。 持这一观点的人会使用 rebase 及 filter-branch 等工具来编写故事,怎么方便后来的读者就怎么写。
现在,让我们回到之前的问题上来,到底合并还是变基好?希望你能明白,这并没有一个简单的答案。 Git 是一个非常强大的工具,它允许你对提交历史做许多事情,但每个团队、每个项目对此的需求并不相同。 既然你已经分别学习了两者的用法,相信你能够根据实际情况作出明智的选择。
总的原则是,只对尚未推送或分享给别人的本地修改执行变基操作清理历史, 从不对已推送至别处的提交执行变基操作,这样,你才能享受到两种方式带来的便利。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值