Re: [PATCH 1/1] git-p4: add unshelve command

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 13 May 2018 at 14:52, Merland Romain <merlorom@xxxxxxxx> wrote:
> Hello Luke,
>
> Very interseting
> This is indeed an option we are waiting since the introduction of option --shelve for git p4 submit
> What I like most in your approach is the preservation of link to p4/master inducing small changes of git-p4 existing functions already heavily tested.
> Also I like the dedicated branch you create, it is cleaner and then we can cherry-pick in other git branches.

Thanks, I'd be interested to know how you get on with it!

> We made some basic tries on our side, just adding an option --unshelve to P4Submit (for simplicity, but I like much more your P4Unshelve class)
> and trying to use the diff of p4 to generate a patch when possible, then apply it in the current git branch on top of HEAD.
> Here it is, hope it can help a bit.
> Note it also uses p4 print -o for binary files.

I did try something like this earlier this year (if you look in the
archives you'll find it) but I found that it was getting quite
complicated trying to construct a sensible looking patch file from the
output of p4 describe. Better to let git's existing tools do that, as
they're going to be better than any half-baked attempt I might manage
in Python!

Thanks!
Luke



>
> diff --git a/git-p4.py b/git-p4.py
> index f4a6f3b4c..b466b46e1 100755
> --- a/git-p4.py
> +++ b/git-p4.py
> @@ -1353,6 +1353,8 @@ class P4Submit(Command, P4UserMap):
>                                       metavar="CHANGELIST",
>                                       help="update an existing shelved changelist, implies --shelve, "
>                                             "repeat in-order for multiple shelved changelists"),
> +                optparse.make_option("--unshelve", dest="unshelve",
> +                                     help="unshelve speficied ChangeList into current BRANCH."),
>                  optparse.make_option("--commit", dest="commit", metavar="COMMIT",
>                                       help="submit only the specified commit(s), one commit or xxx..xxx"),
>                  optparse.make_option("--disable-rebase", dest="disable_rebase", action="store_true",
> @@ -1367,6 +1369,7 @@ class P4Submit(Command, P4UserMap):
>          self.dry_run = False
>          self.shelve = False
>          self.update_shelve = list()
> +        self.unshelve = ""
>          self.commit = ""
>          self.disable_rebase = False
>          self.prepare_p4_only = False
> @@ -2083,6 +2086,66 @@ class P4Submit(Command, P4UserMap):
>          if self.clientPath == "":
>              die("Error: Cannot locate perforce checkout of %s in client view" % self.depotPath)
>
> +        # special case of unshelving
> +        # todo: put this code in a class like P4Sync or P4Rebase
> +        if self.unshelve != "":
> +            git_dir = os.getcwd() + '/'
> +            print "Importing shelved CL %s into current git branch %s" % (self.unshelve, self.master)
> +            description = p4_describe(self.unshelve)
> +
> +            # get changed files
> +            files = p4CmdList(['files', "@=%s" % self.unshelve])
> +            editedFiles = []
> +            filesToAdd = []
> +            filesToDelete = []
> +            binaryFiles = []
> +            something_to_commit = False
> +            for f in files:
> +                if not f["depotFile"].startswith(self.depotPath):
> +                    print "WARNING: file %s not in this p4 depot - skipping" % f["depotFile"]
> +                    continue
> +
> +                elif f["action"] == 'delete':
> +                    filesToDelete.append(f)
> +                    something_to_commit = True
> +                elif f["action"] == 'add':
> +                    filesToAdd.append(f)
> +                    something_to_commit = True
> +                elif f["type"] == 'binary':
> +                    binaryFiles.append(f)
> +                    something_to_commit = True
> +                elif f["action"] == 'edit':
> +                    editedFiles.append(f)
> +                    something_to_commit = True
> +
> +                f["clientFile"] = f["depotFile"].replace(self.depotPath,self.clientPath)
> +                f["gitFile"] = f["depotFile"].replace(self.depotPath,git_dir)
> +
> +            if not something_to_commit:
> +                print "Nothing to commit. Exiting"
> +                return True
> +
> +            # get the diff and copy to diff directory
> +            for f in editedFiles:
> +                p4diff = p4_read_pipe(['diff2', '-du', f["depotFile"]+'#'+f["rev"], f["depotFile"]+'@='+self.unshelve])
> +                p4diff = "\n".join(p4diff.split("\n")[1:])
> +                p4diff = '--- '+f["gitFile"]+'\n' + '+++ '+f["gitFile"]+'\n' + p4diff
> +                write_pipe(['patch', '-d/', '-p0'], p4diff)
> +                write_pipe(['git', 'add', '-f', f["gitFile"]], "")
> +            for f in filesToAdd:
> +                p4_write_pipe(['print', '-o', f["gitFile"], f["depotFile"]+'@='+self.unshelve], "")
> +                write_pipe(['git', 'add', '-f', f["gitFile"]], "")
> +            for f in filesToDelete:
> +                os.remove(f["gitFile"])
> +                write_pipe(['git', 'rm', f["gitFile"]], "")
> +            for f in binaryFiles:
> +                p4_write_pipe(['print', '-o', f["gitFile"], f["depotFile"]+'@='+self.unshelve], "")
> +                write_pipe(['git', 'add', '-f', f["gitFile"]], "")
> +
> +            # finalize: commit in git
> +            write_pipe(['git', 'commit', '-m', description["desc"]], "")
> +            return True
> +
>          print "Perforce checkout for depot path %s located at %s" % (self.depotPath, self.clientPath)
>          self.oldWorkingDirectory = os.getcwd()
>
> Romain
>
>
>
> Le samedi 12 mai 2018 à 23:24:48 UTC+2, Luke Diamand <luke@xxxxxxxxxxx> a écrit :
>
>
>
>
>
> This can be used to "unshelve" a shelved P4 commit into
> a git commit.
>
> For example:
>
>   $ git p4 unshelve 12345
>
> The resulting commit ends up in the branch:
>   refs/remotes/p4/unshelved/12345
>
> If that branch already exists, it is renamed - for example
> the above branch would be saved as p4/unshelved/12345.1.
>
> Caveat:
>
> The unshelving is done against the current "p4/master" branch;
> git-p4 uses "p4 print" to get the file contents at the requested
> revision, and then fast-import creates a commit relative to p4/master.
>
> Ideally what you would want is for fast-import to create the
> commit based on the Perforce "revision" prior to the shelved commit,
> but Perforce doesn't have such a concept - to do this, git-p4
> would need to figure out the revisions of the individual files
> before the shelved changelist, and then construct a temporary
> git branch which matched this.
>
> It's possible to do this, but doing so makes this change a lot more
> complicated.
>
> This limitation means that if you unshelve a change where some
> of the changed files were not based on p4/master, you will get
> an amalgam of the change you wanted, and these other changes.
>
> The reference branch can be changed manually with the "--origin"
> option.
>
> The change adds a new Unshelve command class. This just runs the
> existing P4Sync code tweaked to handle a shelved changelist.
>
> Signed-off-by: Luke Diamand <luke@xxxxxxxxxxx>




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux