Perforce 用户的 Git

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3656351/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 09:03:37  来源:igfitidea点击:

Git for Perforce users

gitperforce

提问by Laurence Gonsalves

I've been using Perforce for a number of years. I'd like to switch to using git for my personal code, but all of the git tutorials that I've seen either assume that you'e a complete source control n00b (which makes them incredibly tedious) or that you're used to svn (which I'm not).

我已经使用 Perforce 很多年了。我想改用 git 来编写我的个人代码,但是我看过的所有 git 教程都假设你是一个完整的源代码控制 n00b(这使得它们非常乏味)或者你已经习惯了svn(我不是)。

I know p4, and I also understand the idea behind a distributed source control system (so I don't need a sales pitch, thanks). What I'd like is a translation table from p4 command to equivalent git commands, as well as the "can't live without" commands that have no p4 equivalent.

我知道 p4,而且我也了解分布式源代码控制系统背后的想法(所以我不需要推销,谢谢)。我想要的是从 p4 命令到等效 git 命令的转换表,以及没有 p4 等效命令的“不能没有”命令。

Since I suspect every p4 user uses a different subset of p4, here are some of the things I regularly do in p4 that I'd like to be able to do in git that aren't immediately obvious from the docs I've looked at:

因为我怀疑每个 p4 用户都使用 p4 的不同子集,所以这里有一些我经常在 p4 中做的事情,我希望能够在 git 中做这些事情,从我看过的文档中并不明显:

  1. create multiple pending changelists in a single client. (p4 change)
  2. edit a pending changelist. (also p4 change)
  3. see a list of all of my pending changelists (p4 changes -s pending)
  4. list of all of the changed files in my client (p4 opened) or in a pending changelist (p4 describe)
  5. see a diff of a pending changelist (I use a wrapper script for this which uses p4 diffand p4 describe)
  6. for a given file, see which submitted changelists affected which lines (p4 annotate)
  7. for a given file, see a list of the descriptions of the changelists that affected the file (p4 log)
  8. submit a pending changelist (p4 submit -c)
  9. abort a pending changelist (p4 revert)
  1. 在单个客户端中创建多个挂起的更改列表。( p4 change)
  2. 编辑挂起的更改列表。(也p4 change
  3. 查看我所有待处理更改列表的列表 ( p4 changes -s pending)
  4. 我的客户端 ( p4 opened) 或挂起的更改列表 ( p4 describe)中所有已更改文件的列表
  5. 查看未决更改列表的差异(我为此使用了一个包装脚本,它使用p4 diffp4 describe
  6. 对于给定的文件,查看哪些提交的更改列表影响了哪些行 ( p4 annotate)
  7. 对于给定的文件,请参阅影响该文件的更改列表的描述列表 ( p4 log)
  8. 提交待处理的变更列表 ( p4 submit -c)
  9. 中止挂起的更改列表 ( p4 revert)

A lot of these revolve around "changelists". "changelist" is p4 terminology. What's the git equivalent term?

其中很多都围绕“变更列表”。“变更列表”是 p4 术语。git 的等效术语是什么?

It sounds like branches might be what git users use in place of what p4 calls changelists. A bit confusing, since p4 also has something called a branch though they seem to be only vaguely related concepts. (Though I always thought p4's concept of a branch was pretty weird it is different yet again from the classic RCS concept of a branch.)

听起来分支可能是 git 用户用来代替 p4 调用的更改列表的东西。有点令人困惑,因为 p4 也有一个叫做分支的东西,尽管它们似乎只是模糊的相关概念。(虽然我一直认为 p4 的分支概念很奇怪,但它又与经典的 RCS 分支概念不同。)

Anyway... I'm not sure how to accomplish what I normally do in p4 changelists with git's branches. In p4 I can do something like this:

无论如何......我不知道如何完成我通常在带有 git 分支的 p4 更改列表中所做的事情。在 p4 我可以做这样的事情:

$ p4 edit a.txt
$ p4 change a.txt
Change 12345 created.

At this point I have a changlist that contains a.txt. I can edit the description and continue working without submitting the changelist. Also, if it turns out that I need to make some changes to some other files, like say a bugfix in some other layer of the code, I can do that in the same client:

在这一点上,我有一个包含 a.txt 的 changlist。我可以编辑描述并在不提交更改列表的情况下继续工作。此外,如果事实证明我需要对其他一些文件进行一些更改,例如在代码的其他某个层进行错误修复,我可以在同一个客户端中执行此操作:

$ p4 edit z.txt
$ p4 change z.txt
Change 12346 created.

Now I have two separate changelists in the same client. I can work on these concurrently, and I don't need to do anything to "switch between" them. When it comes time to commit, I can submit them separately:

现在我在同一个客户端中有两个单独的更改列表。我可以同时处理这些,而且我不需要做任何事情来“切换”它们。当需要提交时,我可以单独提交它们:

$ p4 submit -c 12346  # this will submit the changes to z.txt
$ p4 submit -c 12345  # this will submit the changes to a.txt

I can't figure out how to replicate this in git. From my experiments, it doesn't appear that git addis associated with the current branch. As far as I can tell, when I git commitit's going to commit all files that I git add-ed no matter what branch I was in at the time:

我不知道如何在 git 中复制它。从我的实验来看,它似乎git add与当前分支无关。据我所知,当我git commit要提交所有我git add-ed 的文件时,无论我当时在哪个分支:

$ 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

In this example, the aardvark and zebra branches seem to contain exactly the same set of changes, and based on the output of git statusit appears that doing a commit in either will have the same effect. Am I doing something wrong?

在这个例子中, aardvark 和 zebra 分支似乎包含完全相同的一组更改,并且根据输出,git status似乎在任何一个中执行提交都会产生相同的效果。难道我做错了什么?

采纳答案by slebetman

I haven't used perforce much so this may not be exactly be a 1:1 translation. Then again distributed source control systems like git and mercurial have a different workflow anyway so there really isn't (and there shouldn't) be a 1:1 translation. Anyway, here goes:

我没有经常使用 perforce,所以这可能不完全是 1:1 的翻译。然后,像 git 和 mercurial 这样的分布式源代码控制系统无论如何都有不同的工作流程,所以真的没有(也不应该)1:1 的翻译。无论如何,这里是:

  • Create multiple pending changelists -> Use branches instead. In git branches are light and quick, takes less than a second to create and typically less than two seconds to merge. Don't be afraid of branching and rebase often.

    git branch new-branch-name
    git checkout new-branch-name
    

    Or do it all in one line:

    git checkout -b new-branch-name
    
  • See a list of all pending changelists -> Since the equivalent of multiple pending changelist is multiple branches just view the branches:

    git branch
    

    If you want to view remote branches as well:

    git branch -a
    

    It is considered good practice to immediately delete a branch after a successful merge so you don't have to keep track of which branch are pending to be merged and which have already been merged.

  • List all changed files -> For a single pending "changelist" in a specific branch git has a concept of the index or cache. In order to commit a change you must first add files to this index. This allows you to manually select which group of files represent a single change or to ignore irrelevant files. To see the status of which files are added, or not to this index just do:

    git status
    
  • See a diff of a pending changelist -> There are two parts to this. First to see a diff between the working directory and the index:

    git diff
    

    But if you want to know the diff between what you're typing now and the last commit then you are really asking for a diff between the working directory+index and the HEAD:

    git diff HEAD
    
  • For a given file, see which submitted changelists affected which lines -> This is easy:

    git blame filename
    

    or even better, if you are in a windowing environment:

    git gui blame filename
    

    Git gui takes longer to parse the file (it was written in tcl instead of C) but it has lots of neat features including the ability to "time travel" back into the past by clicking on a commit ID. I only wish they'd implement a feature to "time travel" to the future so I can find out how a given bug will finally be resolved ;-)

  • For a given file, see a list of the descriptions of the changelists that affected the file -> also easy:

    git log filename
    

    But git log is a much more powerful tool than just this. In fact most of my personal scripts piggyback off-of git log to read the repository. Read the man page.

  • Submit a pending changelist -> Also easy:

    git commit
    
  • 创建多个挂起的更改列表 -> 改用分支。在 git 中,分支轻巧快捷,创建时间不到一秒钟,合并通常不到两秒钟。不要害怕经常分支和变基。

    git branch new-branch-name
    git checkout new-branch-name
    

    或者在一行中完成所有操作:

    git checkout -b new-branch-name
    
  • 查看所有挂起更改列表的列表 -> 由于多个挂起更改列表的等效项是多个分支,因此只需查看分支:

    git branch
    

    如果您还想查看远程分支:

    git branch -a
    

    在成功合并后立即删除分支被认为是一种很好的做法,这样您就不必跟踪哪些分支等待合并,哪些已经合并。

  • 列出所有更改的文件 -> 对于特定分支中的单个挂起“更改列表”,git 具有索引或缓存的概念。为了提交更改,您必须首先将文件添加到此索引。这允许您手动选择代表单个更改的文件组或忽略不相关的文件。要查看哪些文件被添加或不添加到此索引的状态,只需执行以下操作:

    git status
    
  • 查看待处理更改列表的差异 -> 有两个部分。首先查看工作目录和索引之间的差异:

    git diff
    

    但是如果你想知道你现在输入的内容和最后一次提交之间的差异,那么你实际上是在要求工作目录+索引和 HEAD 之间的差异:

    git diff HEAD
    
  • 对于给定的文件,查看哪些提交的更改列表影响了哪些行 -> 这很简单:

    git blame filename
    

    甚至更好,如果您在窗口环境中:

    git gui blame filename
    

    Git gui 解析文件需要更长的时间(它是用 tcl 而不是 C 编写的),但它具有许多简洁的功能,包括通过单击提交 ID 来“时间旅行”回到过去的能力。我只希望他们能够实现一个功能来“时间旅行”到未来,这样我就可以找出最终将如何解决给定的错误;-)

  • 对于给定的文件,请参阅影响该文件的更改列表的描述列表 -> 也很简单:

    git log filename
    

    但是 git log 是一个比这更强大的工具。事实上,我的大部分个人脚本都搭载了 git log 来读取存储库。阅读手册页。

  • 提交待处理的更改列表 -> 也很简单:

    git commit
    

See my answer to a previous question to see my typical git workflow: Learning Git. Need to know if I am on the right track

查看我对上一个问题的回答以了解我的典型 git 工作流程:Learning Git。需要知道我是否在正确的轨道上

If you follow the workflow I outlined then you'll find tools like gitk to be much more valuable since it allows you to clearly see groups of changes.

如果您遵循我概述的工作流程,那么您会发现像 gitk 这样的工具更有价值,因为它可以让您清楚地看到更改组。



Additional answer:

补充回答:

Git is very flexible and there are several ways to do what you describe. The thing to remember is to always start a new branch for each feature you're working on. This means the master branch isn't touched so you can always go back to it to do bug fixes. Working in git one should almost always start with:

Git 非常灵活,有多种方法可以执行您所描述的操作。要记住的事情是始终为您正在处理的每个功能启动一个新分支。这意味着 master 分支不会被触及,因此您可以随时返回它进行错误修复。在 git 中工作几乎总是从以下几点开始:

git checkout -b new-feature-a

Now you can edit file a.txt. To work concurrently on another feature do:

现在您可以编辑文件 a.txt。要同时处理另一个功能,请执行以下操作:

git checkout master
git checkout -b new-feature-z

Now you can edit file z.txt. To switch back to a.txt:

现在您可以编辑文件 z.txt。切换回 a.txt:

git checkout new-feature-a

But wait, there are changes to new-feature-z and git won't let you switch branches. At this point you have two choices. The first is the simplest, commit all changes to the current branch:

但是等等,new-feature-z 有一些变化,git 不会让你切换分支。此时你有两个选择。第一个是最简单的,将所有更改提交到当前分支:

git add .
git commit
git checkout new-feature-a

This is what I'd recommend. But if you are really not ready to commit the code, you can temporarily stash it:

这是我推荐的。但是如果你真的没有准备好提交代码,你可以暂时隐藏它:

git stash

Now you can switch to branch new-feature-a. To go back to the code you were working on just pop the stash:

现在您可以切换到分支 new-feature-a。要返回您正在处理的代码,只需弹出存储:

git checkout new-feature-z
git stash pop

When all is done merge back all changes to master:

全部完成后,将所有更改合并回 master:

git merge --no-ff new-feature-a
git merge --no-ff new-feature-z

Because merges are so quick and easy (easy because conflicts are so rare and conflict resolution, when one does happen, not too hard) we use branches in git for everything.

因为合并是如此快速和容易(容易,因为冲突是如此罕见和冲突解决,当发生时,不是太难)我们在 git 中使用分支来处理所有事情。

Here's another example of a common use of branches in git that you don't see in other source control tools (except perhaps mercurial):

这是在 git 中常见分支的另一个示例,您在其他源代码控制工具中看不到(可能除了 mercurial):

Need to keep changing your config files to reflect your dev environment? Then use a branch:

需要不断更改您的配置文件以反映您的开发环境吗?然后使用一个分支:

git checkout -b dev-config

Now edit your config files in your favourite editor then commit changes:

现在在您最喜欢的编辑器中编辑您的配置文件,然后提交更改:

git add .
git commit

Now every new branch can start from the dev-config branch instead of master:

现在每个新分支都可以从 dev-config 分支而不是 master 开始:

git checkout dev-config
git checkout -b new-feature-branch

Once you're done remove the edits in dev-config from new-feature-branch using interactive rebase:

完成后,使用交互式 rebase 从 new-feature-branch 中删除 dev-config 中的编辑:

git rebase -i master

Delete the commits you don't want then save. Now you have a clean branch without custom config edits. Time to merge back to master:

删除您不想要的提交,然后保存。现在你有一个干净的分支,没有自定义配置编辑。是时候合并回master了:

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

It should be noted that removing edits with git rebase -ieven works when all changes happen in the same file. Git remembers changes, not file content*.

应该注意的是,git rebase -i当所有更改都发生在同一个文件中时,删除编辑甚至可以工作。Git 记住更改,而不是文件内容*。

*note: actually, technically not entirely true but as a user that's what it feels like

*注意:实际上,技术上并不完全正确,但作为用户的感觉就是这样



More additional answer:

更多附加答案:

So, from you comments it looks like you want to have two branches to exist simultaneously so you can test how the combined code works. Well, this is a good way to illustrate the power and flexibility of branches.

因此,根据您的评论,您似乎希望同时存在两个分支,以便您可以测试组合代码的工作方式。嗯,这是一个很好的方式来说明分支的力量和灵活性。

First, a word on the implication of cheap branching and modifiable history on your workflow. When I was using CVS and SVN I was always a bit reluctant to commit. That's because committing unstable code would inevitably f**k up other people's working code. But with git I lost that fear. That's because in git other people won't get my changes until I merge them to master. So now I find myself committing code every 5 lines I write. You don't need perfect foresight to commit. You just need to change your mindset: commit-to-branch==add-to-changeset, merge-to-master==commit-changeset.

首先,谈谈廉价分支和可修改历史对您的工作流程的影响。当我使用 CVS 和 SVN 时,我总是有点不愿意提交。那是因为提交不稳定的代码将不可避免地搞砸其他人的工作代码。但是有了 git,我就不再害怕了。那是因为在 git 中,在我将它们合并到 master 之前,其他人不会得到我的更改。所以现在我发现自己每写 5 行代码就提交一次代码。你不需要完美的远见就可以做出承诺。你只需要改变你的心态:commit-to-branch==add-to-changeset,merge-to-master==commit-changeset。

So, back to examples. Here's how I would do it. Say you have a branch new-feature-zand you want to test it with new-feature-a. I would just create a new branch to test it:

所以,回到例子。这是我将如何做到的。假设你有一个分支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

Now you can test. If you need to modify something to make feature-z work with feature-a then do so. If so you can merge back the changes to the relevant branch. Use git rebase -ito remove irrelevant changes from the merge.

现在可以测试了。如果您需要修改某些内容以使 feature-z 与 feature-a 一起使用,请这样做。如果是这样,您可以将更改合并回相关分支。用于git rebase -i从合并中删除不相关的更改。

Alternatively, you can also use git rebase to temporarily change the base of new-feature-z to point to new-feature-a:

或者,您也可以使用 git rebase 临时更改 new-feature-z 的 base 以指向 new-feature-a:

# assume we are currently in branch new-feature-z
git rebase new-feature-a

Now the branch history is modified so that new-feature-z will be based off new-feature-a instead of master. Now you can test. Any changes committed in this branch will belong to the branch new-feature-z. If you need to modify new-feature-a just switch back to it and the rebase to get the new changes:

现在分支历史被修改,以便 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

When you're done, simply rebase back to master to remove changes from new-feature-a:

完成后,只需 rebase 回 master 即可删除 new-feature-a 中的更改:

# assume we are currently in branch new-feature-z
git rebase master

Don't be afraid to start a new branch. Don't be afraid to start a throwaway branch. Don't be afraid to throw away branches. And since merge==submit and commit==add-to-changeset don't be afraid to commit often. Remember, commit is a developer's ultimate undo tool.

不要害怕开始一个新的分支。不要害怕开始一个一次性的分支。不要害怕扔掉树枝。并且由于 merge==submit 和 commit==add-to-changeset 不要害怕经常提交。请记住,提交是开发人员的终极撤消工具。

Oh, and another thing, in git deleted branches still exist in your repository. So if you've accidentally deleted something that you later realise is useful after all you can always get it back by searching the history. So don't be afraid to throw away branches.

哦,还有一件事,在 git 中删除的分支仍然存在于您的存储库中。因此,如果您不小心删除了一些后来发现很有用的内容,您始终可以通过搜索历史记录来找回它。所以不要害怕扔掉树枝。

回答by Jakob Borg

I don't have enough p4 experience to produce an actual cheat sheet, but there are at least some similarities to fall back on. A p4 "changeset" is a git "commit".

我没有足够的 p4 经验来制作实际的备忘单,但至少有一些相似之处可以依靠。p4“变更集”是一个git“提交”。

Changes to your local work space get added to the "index" with git add, and the index later gets committed with git commit. So the index is your pending changelist, for all intents and purposes.

对本地工作空间的更改通过 被添加到“索引”中git add,然后索引被提交git commit。因此,出于所有意图和目的,索引是您的待定更改列表。

You look at changes with git diffand git status, where git diffusually shows changes between the workspace and the index, but git diff --cachedshows changes between the index and the repository (= your pending changelist).

您使用git diff和查看更改git status,其中git diff通常显示工作区和索引git diff --cached之间的更改,但显示索引和存储库之间的更改(= 待处理的更改列表)。

For more in depth information, I recommend http://progit.org/book/. Since you know version control in general, you can probably skim a lot of it and extract the git-specific information...

要获得更深入的信息,我推荐http://progit.org/book/。由于您通常了解版本控制,因此您可能可以略读其中的很多内容并提取特定于 git 的信息......

回答by Elias Bachaalany

I suffer like you with the lack of the "changelist" concept which is not exactly the same as git branches.

我和你一样因为缺少与 git 分支不完全相同的“变更列表”概念而受苦。

I would write a small script that will create a changelist file with the list of files in that changelist.

我会编写一个小脚本,该脚本将创建一个更改列表文件,其中包含该更改列表中的文件列表。

Another command to submit just a certain changelist by simply calling git commit -a @change_list_contents.txt and then "git commit"

通过简单地调用 git commit -a @change_list_contents.txt 然后“git commit”来提交某个更改列表的另一个命令

Hope that helps, Elias

希望有帮助,埃利亚斯

回答by Russell Gallop

There is a more lightweight alternative in git that could form part of your workflow; using the git staging area.

git 中有一个更轻量级的替代方案,可以构成您工作流程的一部分;使用 git 暂存区。

I often just make changes then submit as several commits (e.g. add debug statements, refactor, actually fix a bug). Rather than setting up your perforce changelists, then make changes, then submit, you can just make your changes then choose how to submit them (optionally using the git staging area).

我经常只是进行更改,然后作为多次提交提交(例如,添加调试语句、重构、实际修复错误)。而不是设置你的 perforce 更改列表,然后进行更改,然后提交,您只需进行更改然后选择如何提交它们(可选地使用 git 暂存区)。

You can commit particular files from the command line with:

您可以使用以下命令从命令行提交特定文件:

git commit a.txt
git commit z.txt

Or explicitly staging the files first:

或者首先明确暂存文件:

git add a.txt
git commit
git add z.txt
git commit

git gui will let you select lines or hunks from within files to build up a commit in the staging area. This is very useful if you have changes in one file that you want to be in different commits. Having moved from git to perforce and this is one thing that I really miss.

git gui 将允许您从文件中选择行或大块以在暂存区构建提交。如果您希望在不同提交中对一个文件进行更改,这将非常有用。从 git 转移到 perforce,这是我真正想念的一件事。

There is a small caveat to bear in mind with this workflow. If you make changes A and B to a file, test the file, then commit A then you haven't tested that commit (independently of B).

对于此工作流程,需要牢记一个小警告。如果您对文件进行了更改 A 和 B,测试该文件,然后提交 A,那么您还没有测试该提交(独立于 B)。

回答by dgnuff

Having used both Perforce and git fairly extensively, there's only one way I can see to get anywhere near Perforce changelists with git.

在相当广泛地使用 Perforce 和 git 之后,只有一种方法可以让我看到使用 git 接近 Perforce 更改列表的任何地方。

The first thing to understand is that to correctly implement this functionality in git in such a way that it's a not a complete kluge, e.g. trying to shoehorn it into branches, would require the following change: git would require multiple staging areas for a single branch.

首先要理解的是,要在 git 中正确实现此功能,使其不是一个完整的 kluge,例如尝试将其硬塞到分支中,则需要进行以下更改:git 将需要单个分支的多个暂存区域.

Perforce changelists permit a workflow that simply has no equivalent in git. Consider the following workflow:

Perforce 更改列表允许在 git 中没有等效项的工作流。考虑以下工作流程:

Check out a branch
Modify file A and add it to changelist 1
Modify file B and add it to changelist 2

If you try to do this using branches in git you'll wind up with two branches, one of which has the changes to file A, the other has the changes to file B, but no place where you can see the changes to both files Aand Bat the same time.

如果您尝试使用 git 中的分支来执行此操作,您将得到两个分支,其中一个更改了 file A,另一个更改了 file B,但没有地方可以看到对这两个文件ABat的更改同时。

The closest approximation I can see is to use git add . -pand then use the 'a'and 'd'sub-commands to select or reject entire files. However that's not quite the same, and the difference here stems from a fundamental disparity in the general modus operandi of the two systems.

我能看到的最接近的近似是使用git add . -p然后使用'a''d'子命令来选择或拒绝整个文件。然而,这并不完全相同,这里的差异源于两个系统的一般操作方式的根本差异。

Git (and subversion, not that it matters for this discussion) allow a file to be changed without telling anyone about this ahead of time. You just change a file, and then let git sort it all out when you commit the changes. Perforce requires you to actively check out a file before changes are allowed, and it is for this reason that changelists have to exist. In essence, Perforce requires you to add a file to the index before changing it. Hence the necessity for multiple changelists in Perforce, and also the reason why git has no equivalent. It simply doesn't need them.

Git(和 subversion,这与本次讨论无关)允许更改文件而无需提前告诉任何人。您只需更改一个文件,然后在提交更改时让 git 将其全部整理出来。Perforce 要求您在允许更改之前主动检出文件,因此必须存在更改列表。本质上,Perforce 要求您在更改文件之前将文件添加到索引中。因此在 Perforce 中需要多个更改列表,这也是 git 没有等效项的原因。 它根本不需要它们。

回答by VonC

With Git 2.27 (Q2 2020), "git p4" learned four new hooks and also "--no-verify" option to bypass them (and the existing "p4-pre-submit" hook).

在 Git 2.27(2020 年第 2 季度)中,“ git p4”学习了四个新钩子以及“ --no-verify”绕过它们的选项(以及现有的“ p4-pre-submit”钩子)。

See commit 1ec4a0a, commit 38ecf75, commit cd1e0dc(14 Feb 2020), and commit 4935c45, commit aa8b766, commit 9f59ca4, commit 6b602a2(11 Feb 2020) by Ben Keene (seraphire).
(Merged by Junio C Hamano -- gitster--in commit 5f2ec21, 22 Apr 2020)

提交1ec4a0a提交38ecf75提交cd1e0dc(2020年2月14日),以及提交4935c45提交aa8b766提交9f59ca4提交6b602a2(2020年2月11日)由本基恩(seraphire
(由Junio C gitsterHamano合并-- --在2020 年 4 月 22 日提交 5f2ec21 中

git-p4: add p4 submit hooks

Signed-off-by: Ben Keene

The git command "commit" supports a number of hooks that support changing the behavior of the commit command.

The git-p4.pyprogram only has one existing hook, "p4-pre-submit".

This command occurs early in the process.

There are no hooks in the process flow for modifying the P4 changelist text programmatically.

Adds 3 new hooks to git-p4.pyto the submit option.

The new hooks are:

  • p4-prepare-changelist- Execute this hook after the changelist file has been created.
    The hook will be executed even if the --prepare-p4-onlyoption is set.
    This hook ignores the --no-verifyoption in keeping with the existing behavior of git commit.

  • p4-changelist- Execute this hook after the user has edited the changelist.
    Do not execute this hook if the user has selected the --prepare-p4-onlyoption.
    This hook will honor the --no-verify, following the conventions of git commit.

  • p4-post-changelist- Execute this hook after the P4 submission process has completed successfully.
    This hook takes no parameters and is executed regardless of the --no-verifyoption.

It's return value will not be checked.

The calls to the new hooks: p4-prepare-changelist, p4-changelist, and p4-post-changelistshould all be called inside the try-finally block.

git-p4: 添加 p4 提交钩子

签字人:本·基恩

git 命令“ commit” 支持许多支持更改提交命令行为的钩子。

git-p4.py程序只有一个现有的钩子,“ p4-pre-submit”。

此命令发生在进程的早期。

流程中没有用于以编程方式修改 P4 更改列表文本的挂钩。

git-p4.py向提交选项添加 3 个新钩子。

新的钩子是:

  • p4-prepare-changelist- 在创建更改列表文件后执行此挂钩。
    即使--prepare-p4-only设置了该选项,钩子也会被执行。
    这个钩子忽略了--no-verify与 的现有行为保持一致的选项git commit

  • p4-changelist- 在用户编辑更改列表后执行此钩子。
    如果用户选择了该--prepare-p4-only选项,则不要执行此挂钩。
    这个钩子将--no-verify遵循git commit.

  • p4-post-changelist- 在 P4 提交过程成功完成后执行此钩子。
    这个钩子不带参数,无论--no-verify选项如何都会执行。

它的返回值不会被检查。

对新钩子的调用:p4-prepare-changelistp4-changelistp4-post-changelist都应该在 try-finally 块内调用。

回答by Toby Allen

This doesn't answer your question specifically, but I don't know if you are aware that a 2 User, 5 Workspace version of perforce is free to download and use from the perforce website.

这并没有具体回答您的问题,但我不知道您是否知道 perforce 的 2 User, 5 Workspace 版本可以从perforce 网站免费下载和使用。

This way you can use perforce at home for your personal projects if you wish. The one annoyance is the 5 workspaces which can be a bit limiting, but its pretty incredible to have perforce available for home use.

通过这种方式,如果您愿意,您可以在家中将 perforce 用于您的个人项目。一个烦恼是 5 个工作区,这可能有点限制,但能够在家使用 perforce 是非常令人难以置信的。