我一直在使用Perforce多年.我想切换到使用git作为我的个人代码,但是我见过的所有git教程都假定你是一个完整的源代码控制n00b(这使得它们非常繁琐)或者你已经习惯了svn(我不是).
我知道p4,我也理解分布式源代码控制系统背后的想法(所以我不需要销售推销,谢谢).我想要的是从p4命令到等效git命令的转换表,以及没有p4等效的"不能没有"命令.
因为我怀疑每个p4用户都使用了不同的p4子集,所以这里有一些我经常在p4中做的事情,我希望能够在git中完成这些事情,这些事情从我看过的文档中看不出来:
p4 change)p4 change)p4 changes -s pending)p4 opened)或待定更改列表(p4 describe)中所有已更改文件的列表p4 diff和p4 describe)p4 annotate)p4 log)p4 submit -c)p4 revert)其中很多都围绕着"变革清单"."changelist"是p4术语.什么是git等效术语?
听起来像分支可能是git用户使用的代替p4调用更改列表的东西.有点混乱,因为p4也有一个叫做分支的东西,虽然它们似乎只是模糊的相关概念.(虽然我一直认为p4的分支概念非常奇怪,但它与分支的经典RCS概念不同.)
无论如何......我不知道如何通过git的分支来完成我通常在p4更改列表中所做的事情.在p4中,我可以这样做:
$ p4 edit a.txt
$ p4 change a.txt
Change 12345 created.
Run Code Online (Sandbox Code Playgroud)
此时我有一个包含a.txt的changlist.我可以编辑说明并继续工作而无需提交更改列表.此外,如果事实证明我需要对其他一些文件进行一些更改,比如在代码的某些其他层中说错误修复,我可以在同一个客户端中执行此操作:
$ p4 edit z.txt
$ p4 change z.txt
Change 12346 created.
Run Code Online (Sandbox Code Playgroud)
现在我在同一个客户端有两个单独的更改列表.我可以同时处理这些问题,而且我不需要做任何事情来"切换"它们.在提交时,我可以单独提交:
$ p4 submit -c 12346 # this will submit the changes to z.txt
$ p4 submit -c 12345 # this will submit the changes to a.txt
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何在git中复制它.从我的实验来看,它似乎git add与当前分支无关.据我所知,当我git commit将提交所有文件时,git add无论我当时在哪个分支:
$ git init
Initialized empty Git repository in /home/laurence/git-playground/.git/
$ ls
a.txt w.txt z.txt
$ git add -A .
$ git commit
Initial commit.
3 files changed, 3 insertions(+), 0 deletions(-)
create mode 100644 a.txt
create mode 100644 w.txt
create mode 100644 z.txt
$ vi a.txt z.txt
2 files to edit
$ git status
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: a.txt
# modified: z.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git branch aardvark
$ git checkout aardvark
M a.txt
M z.txt
Switched to branch 'aardvark'
$ git add a.txt
$ git checkout master
M a.txt
M z.txt
Switched to branch 'master'
$ git branch zebra
$ git checkout zebra
M a.txt
M z.txt
Switched to branch 'zebra'
$ git add z.txt
$ git status
# On branch zebra
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
# modified: z.txt
#
$ git checkout aardvark
M a.txt
M z.txt
Switched to branch 'aardvark'
$ git status
# On branch aardvark
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
# modified: z.txt
Run Code Online (Sandbox Code Playgroud)
在这个例子中,aardvark和zebra分支似乎包含完全相同的变化集,并且基于它的输出git status似乎在任一个中进行提交将具有相同的效果.难道我做错了什么?
sle*_*man 70
我没有太多使用perforce所以这可能不是1:1的翻译.然后,像git和mercurial这样的分布式源代码控制系统无论如何都有不同的工作流程,因此确实没有(并且不应该)是1:1的翻译.无论如何,这里是:
创建多个挂起的更改列表 - >使用分支.在git中,分支很轻,很快,创建时间不到一秒,合并时间通常不到两秒.不要害怕经常分支和变形.
git branch new-branch-name
git checkout new-branch-name
Run Code Online (Sandbox Code Playgroud)
或者在一行中完成所有操作:
git checkout -b new-branch-name
Run Code Online (Sandbox Code Playgroud)查看所有挂起的更改列表的列表 - >由于多个挂起的更改列表的等效项是多个分支,只需查看分支:
git branch
Run Code Online (Sandbox Code Playgroud)
如果您还想查看远程分支:
git branch -a
Run Code Online (Sandbox Code Playgroud)
成功合并后立即删除分支被认为是一种好习惯,因此您无需跟踪哪些分支待合并以及哪些分支已合并.
列出所有已更改的文件 - >对于特定分支中的单个待处理"更改列表",git具有索引或缓存的概念.要提交更改,您必须先将文件添加到此索引.这允许您手动选择哪个文件组代表单个更改或忽略不相关的文件.要查看添加或不添加到此索引的文件的状态,请执行以下操作:
git status
Run Code Online (Sandbox Code Playgroud)查看待定更改列表的差异 - >这有两个部分.首先看到工作目录和索引之间的差异:
git diff
Run Code Online (Sandbox Code Playgroud)
但是如果你想知道你现在输入的内容和最后一次提交之间的差异,那么你真的要求工作目录+索引和HEAD之间的差异:
git diff HEAD
Run Code Online (Sandbox Code Playgroud)对于给定的文件,请查看哪些提交的更改列表影响了哪些行 - >这很简单:
git blame filename
Run Code Online (Sandbox Code Playgroud)
甚至更好,如果你在窗口环境中:
git gui blame filename
Run Code Online (Sandbox Code Playgroud)
Git gui需要更长的时间来解析文件(它是用tcl而不是C编写的),但它有很多简洁的功能,包括通过点击提交ID"时间旅行"回到过去的能力.我只希望他们实现一个"时间旅行"到未来的功能,这样我就可以找出最终如何解决给定的bug ;-)
对于给定文件,请参阅影响文件的更改列表的描述列表 - >也很简单:
git log filename
Run Code Online (Sandbox Code Playgroud)
但是git log是一个比这更强大的工具.事实上,我的大多数个人脚本都会从git日志中捎带来读取存储库.阅读手册页.
提交待定的更改列表 - >也很简单:
git commit
Run Code Online (Sandbox Code Playgroud)查看我对上一个问题的回答,看看我的典型git工作流程:学习Git.需要知道我是否走在正确的轨道上
如果按照流程我概述,然后你会发现像gitk工具要更有价值,因为它可以让你清楚地看到变化的群体.
Git非常灵活,有几种方法可以完成你所描述的.要记住的是始终为您正在处理的每个功能启动一个新分支.这意味着不会触及主分支,因此您可以随时返回它来修复错误.在git中工作几乎总是应该从:
git checkout -b new-feature-a
Run Code Online (Sandbox Code Playgroud)
现在您可以编辑文件a.txt.要同时使用其他功能,请执行以下操作:
git checkout master
git checkout -b new-feature-z
Run Code Online (Sandbox Code Playgroud)
现在您可以编辑文件z.txt.要切换回a.txt:
git checkout new-feature-a
Run Code Online (Sandbox Code Playgroud)
但是等等,new-feature-z有变化,git不会让你切换分支.此时您有两个选择.第一个是最简单的,提交当前分支的所有更改:
git add .
git commit
git checkout new-feature-a
Run Code Online (Sandbox Code Playgroud)
这是我推荐的.但是如果你真的没准备好提交代码,你可以暂时隐藏它:
git stash
Run Code Online (Sandbox Code Playgroud)
现在您可以切换到分支new-feature-a.要回到您正在处理的代码,只需弹出存储:
git checkout new-feature-z
git stash pop
Run Code Online (Sandbox Code Playgroud)
完成所有操作后,将所有更改合并回master:
git merge --no-ff new-feature-a
git merge --no-ff new-feature-z
Run Code Online (Sandbox Code Playgroud)
因为合并是如此快速和简单(容易因为冲突是如此罕见和冲突解决,当一个确实发生,而不是太难)我们在git中使用分支来处理所有事情.
这是在git中常见的分支的另一个例子,你在其他源代码控制工具中看不到(除了mercurial):
需要不断更改配置文件以反映您的开发环境?然后使用分支:
git checkout -b dev-config
Run Code Online (Sandbox Code Playgroud)
现在,在您喜欢的编辑器中编辑配置文件,然后提交更改:
git add .
git commit
Run Code Online (Sandbox Code Playgroud)
现在每个新分支都可以从dev-config分支而不是master开始:
git checkout dev-config
git checkout -b new-feature-branch
Run Code Online (Sandbox Code Playgroud)
完成后,使用交互式rebase从new-feature-branch中删除dev-config中的编辑:
git rebase -i master
Run Code Online (Sandbox Code Playgroud)
删除您不想要的提交然后保存.现在你有一个没有自定义配置编辑的干净分支.合并回主人的时间:
git checkout master
git merge --no-ff new-feature-branch
# because master have changed, it's a good idea to rebase dev-config:
git checkout dev-config
git rebase master
Run Code Online (Sandbox Code Playgroud)
应该注意的是,git rebase -i当所有更改都发生在同一文件中时,删除编辑甚至可以正常工作.Git会记住更改,而不是文件内容*.
*注意:实际上,技术上并不完全正确,但作为用户感觉就像
因此,从您的评论看起来您希望同时存在两个分支,以便您可以测试组合代码的工作方式.嗯,这是一个很好的方式来说明分支的力量和灵活性.
首先,关于廉价分支和可修改历史在您的工作流程中的含义.当我使用CVS和SVN时,我总是有点不愿意提交.那是因为提交不稳定的代码将不可避免地导致其他人的工作代码.但是随着git我失去了那种恐惧.那是因为在git中,其他人在我将它们合并为master之前不会得到我的更改.所以现在我发现自己每写5行就会提交代码.你不需要完美的先见之明.您只需要改变您的思维方式:commit-to-branch == add-to-changeset,merge-to-master == commit-changeset.
所以,回到例子.我就是这样做的.假设您有一个分支,new-feature-z并且您想要使用它进行测试new-feature-a.我只想创建一个新的分支来测试它:
# assume we are currently in branch new-feature-z
# branch off this branch for testing
git checkout -b feature-z-and-feature-a
# now temporarily merge new-feature-a
git merge --no-ff new-feature-a
Run Code Online (Sandbox Code Playgroud)
现在你可以测试了.如果您需要修改某些内容以使feature-z与feature-a一起使用,那么请执行此操作.如果是这样,您可以将更改合并回相关分支.用于git rebase -i从合并中删除不相关的更改.
或者,您也可以使用git rebase临时更改new-feature-z的基础以指向new-feature-a:
# assume we are currently in branch new-feature-z
git rebase new-feature-a
Run Code Online (Sandbox Code Playgroud)
现在修改了分支历史记录,以便new-feature-z将基于new-feature-a而不是master.现在你可以测试了.在此分支中提交的任何更改都将属于分支new-feature-z.如果您需要修改new-feature-a,只需切换回它并使用rebase获取新的更改:
git checkout new-feature-a
# edit code, add, commit etc..
git checkout new-feature-z
git rebase new-feature-a
# now new-feature-z will contain new changes from new-feature-a
Run Code Online (Sandbox Code Playgroud)
完成后,只需重新绑定到master即可删除new-feature-a中的更改:
# assume we are currently in branch new-feature-z
git rebase master
Run Code Online (Sandbox Code Playgroud)
不要害怕开始新的分支.不要害怕开始一次性分支.不要害怕扔掉树枝.而且由于merge == submit和commit == add-to-changeset不要害怕经常提交.请记住,commit是开发人员的终极撤消工具.
哦,另外一件事,在git中,已删除的分支仍然存在于您的存储库中.因此,如果您不小心删除了以后认为有用的内容,那么您总是可以通过搜索历史记录来获取它.所以不要害怕扔掉树枝.
| 归档时间: |
|
| 查看次数: |
20849 次 |
| 最近记录: |