gpt4 book ai didi

Perforce 用户的 Git

转载 作者:行者123 更新时间:2023-12-01 18:50:04 26 4
gpt4 key购买 nike

我已经使用 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 diffp4 describe )
  • 对于给定文件,查看哪些提交的更改列表影响了哪些行(p4 annotate)
  • 对于给定文件,请参阅影响文件的更改列表的描述列表 (p4 log)
  • 提交待处理的变更列表 (p4 submit -c)
  • 中止挂起的变更列表 (p4 revert)

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

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

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

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

    现在我在同一个客户端中有两个单独的更改列表。我可以同时处理这些,而且我不需要做任何事情来“切换”它们。当需要提交时,我可以单独提交它们:
    $ p4 submit -c 12346  # this will submit the changes to z.txt
    $ p4 submit -c 12345 # this will submit the changes to a.txt

    我不知道如何在 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

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

    最佳答案

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

  • 创建多个挂起的更改列表 -> 改用分支。在 git 中,分支轻巧快捷,创建时间不到一秒钟, merge 通常不到两秒钟。不要害怕经常分支和 rebase 。
    git branch new-branch-name
    git checkout new-branch-name

    或者在一行中完成所有操作:
    git checkout -b new-branch-name
  • 查看所有待处理变更列表的列表 -> 由于多个待处理变更列表相当于多个分支,因此只需查看分支:
    git branch

    如果您还想查看远程分支:
    git branch -a

    在成功 merge 后立即删除分支被认为是一种很好的做法,这样您就不必跟踪哪些分支等待 merge ,哪些已经 merge 。
  • 列出所有更改的文件 -> 对于特定分支中的单个待处理“更改列表”,git 具有索引或缓存的概念。为了提交更改,您必须首先将文件添加到此索引。这允许您手动选择代表单个更改的文件组或忽略不相关的文件。要查看哪些文件被添加或不添加到此索引的状态,只需执行以下操作:
    git status
  • 查看待处理变更列表的差异 -> 这有两个部分。首先查看工作目录和索引之间的差异:
    git diff

    但是如果你想知道你现在输入的内容和最后一次提交之间的差异,那么你实际上是在要求工作目录+索引和 HEAD 之间的差异:
    git diff HEAD
  • 对于给定的文件,查看哪些提交的更改列表影响了哪些行 -> 这很简单:
    git blame filename

    甚至更好,如果您在窗口环境中:
    git gui blame filename

    Git gui 解析文件需要更长的时间(它是用 tcl 而不是 C 编写的),但它具有许多简洁的功能,包括通过单击提交 ID 来“时间旅行”回到过去的能力。我只希望他们能够实现一个功能来“时间旅行”到 future ,这样我就可以找出最终将如何解决给定的错误 ;-)
  • 对于给定的文件,请参阅影响该文件的更改列表的描述列表 -> 也很简单:
    git log filename

    但是 git log 是一个比这更强大的工具。事实上,我的大部分个人脚本都搭载了 git log 来读取存储库。阅读手册页。
  • 提交待处理的变更列表 -> 也很简单:
    git commit

  • 查看我对上一个问题的回答以了解我的典型 git 工作流程: Learning Git. Need to know if I am on the right track

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

    补充回答:

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

    现在您可以编辑文件 a.txt。要同时处理另一个功能,请执行以下操作:
    git checkout master
    git checkout -b new-feature-z

    现在您可以编辑文件 z.txt。切换回 a.txt:
    git checkout new-feature-a

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

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

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

    全部完成后,将所有更改 merge 回 master:
    git merge --no-ff new-feature-a
    git merge --no-ff new-feature-z

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

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

    需要不断更改您的配置文件以反射(reflect)您的开发环境吗?然后使用一个分支:
    git checkout -b dev-config

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

    现在每个新分支都可以从 dev-config 分支而不是 master 开始:
    git checkout dev-config
    git checkout -b new-feature-branch

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

    删除您不想要的提交,然后保存。现在你有一个干净的分支,没有自定义配置编辑。是时候 merge 回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

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

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

    更多附加答案:

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

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

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

    或者,您也可以使用 git rebase 临时更改 new-feature-z 的 base 以指向 new-feature-a:
    # assume we are currently in branch new-feature-z
    git rebase new-feature-a

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

    完成后,只需 rebase 回 master 即可删除 new-feature-a 中的更改:
    # assume we are currently in branch new-feature-z
    git rebase master

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

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

    关于Perforce 用户的 Git,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3656351/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com