git-p4 -- any great explanations for how it works

There is some more information in Documentation/git-p4.txt in the git project source code.

git-p4 maintains a refs/remotes/p4 branch to mirror the remote Perforce server. By default git-p4 clone and git-p4 sync update this remote and you rebase your master against it.

git-p4 submit requires configuring an additional local directory as the Perforce client root for use by p4 submit.

git-p4 sync/clone will record each Perforce changelist number in the corresponding git commit message. For example:

[git-p4: depot-paths = "//depot/test/": change = 51]

Using these changelist notations, git-p4 sync acquires changelists on the Perforce server not yet committed to git, adding changelist notations to each new git commit message.

git-p4 submit begins by identifying new local git commits - those without [git-p4: ...]. Using the Perforce client local workspace, it syncs down the Perforce files, and with git apply applies the patches gotten from git format-patch on the unsubmitted git commits before calling p4 submit.

Then git-p4 submit calls git-p4 sync to update the ref/remotes/p4 branch against the just updated Perforce remote.

Finally git-p4 submit will call git rebase on the master branch against the updated remote. This results in the same git tree which was submitted, but with edited commit messages containing the [git-p4...] changelist notations.

How does one keep a few files modified in git without ever sending them to p4?

git-p4 submit will submit all branch commits. Use the usual git tools to organize changes into and out of the branch you choose to submit to Perforce.


Regarding "What commits are pending to commit to perforce?"

Any command that can accept a revision range (see gitrevisions(7)) should work, you just have to refer to the p4 remote as an endpoint for the range. For instance:

  • git log remotes/p4/master..master
  • git diff remotes/p4/master..master

I tend to use show-branch to get a quick overview of the state of my branches, in which case git show-branch --all works as well.