<!--order=16-->
<h1>Git: Interoperability and Collaboration</h1>
<p>Git can import from and export to other version control systems, collaborate via email-based patch workflows, and export data in portable formats. This covers the bridging and collaboration commands: SVN and Perforce interop, email-based patch workflows, fast import/export for bulk data transfer, and the remaining commands from <code>git help --all</code>.</p>

<h2>Commands Covered</h2>
<p><code>git svn</code> · <code>git p4</code> · <code>git cvsimport</code> · <code>git cvsexportcommit</code> · <code>git archimport</code> · <code>git send-email</code> · <code>git imap-send</code> · <code>git request-pull</code> · <code>git quiltimport</code> · <code>git fast-export</code> · <code>git fast-import</code></p>

<h2>git svn</h2>
<p>Bidirectional bridge between Git and Subversion. Lets you use Git locally while the "source of truth" remains a Subversion repository. Useful when a team hasn't migrated to Git yet.</p>
<pre>
# Clone a Subversion repository into Git
$ git svn clone http://svn.example.com/project/trunk project
# --stdlayout if the SVN repo has standard trunk/branches/tags structure:
$ git svn clone --stdlayout http://svn.example.com/project project

# Clone only recent history (faster for large repos)
$ git svn clone -r 5000:HEAD http://svn.example.com/project/trunk project

# Fetch new commits from SVN into Git
$ git svn fetch
$ git svn rebase     # fetch + rebase local commits on top

# Push Git commits to SVN (like git push — but to SVN)
$ git svn dcommit

# Show SVN revision information in git log
$ git svn log
$ git log --show-notes=*    # shows svn-remote info

# Find the SVN revision for a Git commit
$ git svn find-rev HEAD
$ git svn find-rev r1234    # find the Git commit for SVN rev 1234

# Create a Git branch from an SVN branch
$ git svn branch feature-x

# Create an SVN tag
$ git svn tag v1.0.0

# Full migration — permanently move an SVN repo to Git
$ git svn clone --stdlayout http://svn.example.com/project myrepo
$ cd myrepo
$ git remote add origin https://github.com/user/myrepo.git
$ git push -u origin --all
$ git push origin --tags
</pre>

<h2>git p4</h2>
<p>Import from and submit to Perforce (p4) repositories. Requires the <code>p4</code> Perforce client to be installed.</p>
<pre>
# Clone a Perforce depot into Git
$ git p4 clone //depot/main@all

# Sync new changes from Perforce into Git
$ git p4 sync

# Submit Git commits back to Perforce
$ git p4 submit

# Clone only recent changelists
$ git p4 clone //depot/main@12345,#head

# Rebase on top of new Perforce changes
$ git p4 rebase

# Show pending submissions
$ git p4 submit --dry-run
</pre>

<h2>CVS Interoperability</h2>
<pre>
# Import a CVS repository into Git
$ git cvsimport -C my-git-repo :pserver:user@host:/cvsroot/module

# Export a single Git commit to a CVS checkout
$ git cvsexportcommit -v abc1234

# Emulate a CVS server (allows CVS clients to access a Git repo)
$ git cvsserver
# Configure via git config (experimental, rarely used today)
</pre>

<h2>git archimport</h2>
<pre>
# Import a GNU Arch repository into Git
$ git archimport user@example.com--my-archive/project--main
# GNU Arch (tla) was an early distributed VCS; rarely encountered today
</pre>

<h2>Email-Based Patch Workflow</h2>
<p>Before GitHub, patches were shared via email — you'd format a commit as a patch file and email it to a project's mailing list. The maintainer would review and apply it. This is still the workflow for the Linux kernel, Git itself, and many other projects.</p>

<h3>git send-email</h3>
<pre>
# Configure git send-email to use your mail server
$ git config --global sendemail.smtpServer smtp.gmail.com
$ git config --global sendemail.smtpServerPort 587
$ git config --global sendemail.smtpEncryption tls
$ git config --global sendemail.smtpUser you@gmail.com

# Send the last commit as a patch to a mailing list
$ git format-patch -1 -o /tmp/patches/
$ git send-email /tmp/patches/0001-Fix-login-bug.patch \
    --to=project-patches@lists.example.com

# Send patches for commits on current branch not in main
$ git send-email --to=patches@example.com main

# Review what would be sent (dry run)
$ git send-email --dry-run --to=patches@example.com main

# Send with a cover letter (series of patches)
$ git format-patch --cover-letter --annotate -o /tmp/patches main
# Edit the cover letter, then:
$ git send-email /tmp/patches/

# Reply to an existing thread (for revised patches)
$ git send-email --in-reply-to="Message-ID@example.com" \
    0001-v2-fix.patch
</pre>

<h3>git imap-send</h3>
<pre>
# Send patches directly to an IMAP drafts folder
# (useful when SMTP is blocked but IMAP works)
$ git config --global imap.host imap.gmail.com
$ git config --global imap.user you@gmail.com
$ git config --global imap.folder "[Gmail]/Drafts"

$ git format-patch --stdout main | git imap-send
# Patches appear as draft emails — review and send manually
</pre>

<h3>git request-pull</h3>
<pre>
# Generate a summary of pending changes for a maintainer
$ git request-pull v1.0 https://github.com/your/fork.git main

# Output (copy into an email):
# The following changes since commit abc1234...:
#
#   commit message (date) (abc1234)
#
# are available in the Git repository at:
#   https://github.com/your/fork.git main
#
# Jason Smith (3):
#   Fix login bug
#   Add search feature
#   Update documentation
#
# ...diff stats...
</pre>

<h2>git quiltimport</h2>
<pre>
# Apply a Quilt patch series as Git commits
$ git quiltimport
# Quilt is a patch management system that organizes patches in a series.
# Common in Linux distribution packaging workflows.

# Import patches from a specific directory
$ git quiltimport --patches /path/to/patches/
</pre>

<h2>git fast-export and git fast-import</h2>
<p>These commands serialize and deserialize Git history in a text-based "fast-import stream" format. Used for migrating between VCS systems, filtering repositories, and bulk data operations.</p>

<h3>git fast-export</h3>
<pre>
# Export all history to fast-import format
$ git fast-export --all &gt; repo.fi

# Export a specific branch
$ git fast-export main &gt; main.fi

# Export with signed tags (verifiable)
$ git fast-export --signed-tags=strip --all &gt; repo.fi

# Export only commits not in another repo (for incremental transfer)
$ git fast-export main ^old-main &gt; incremental.fi

# Export to a file for piping to fast-import
$ git fast-export HEAD | gzip &gt; repo.fi.gz
</pre>

<h3>git fast-import</h3>
<pre>
# Import a fast-import stream into the current repo
$ git fast-import &lt; repo.fi

# Import compressed stream
$ zcat repo.fi.gz | git fast-import

# Import with statistics
$ git fast-import --stats &lt; repo.fi

# Force reference updates
$ git fast-import --force &lt; repo.fi

# Typical VCS migration workflow:
# 1. Export from old VCS to fast-import format (use conversion tool)
$ svn-to-git-migrator &gt; repo.fi
# 2. Create a new Git repo
$ mkdir new-git-repo &amp;&amp; cd new-git-repo &amp;&amp; git init
# 3. Import
$ git fast-import &lt; /path/to/repo.fi
$ git checkout HEAD
</pre>

<h2>Remaining Commands Reference</h2>

<table>
  <thead><tr><th>Command</th><th>What it does</th></tr></thead>
  <tbody>
    <tr><td><code>git citool</code></td><td>Graphical alternative to <code>git commit</code> (tcl/tk GUI)</td></tr>
    <tr><td><code>git gitk</code></td><td>Graphical repository browser (tcl/tk)</td></tr>
    <tr><td><code>git gui</code></td><td>Graphical interface for staging and committing</td></tr>
    <tr><td><code>git gitweb</code></td><td>Web-based Git repository viewer (CGI)</td></tr>
    <tr><td><code>git instaweb</code></td><td>Instantly browse a repo with gitweb in a browser: <code>git instaweb --httpd=webrick</code></td></tr>
    <tr><td><code>git apply</code></td><td>Apply a patch to files and/or to the index (non-mailbox format; compare: <code>git am</code> handles mailbox patches)</td></tr>
    <tr><td><code>git merge-file</code></td><td>Three-way merge of files: <code>git merge-file mine base theirs</code></td></tr>
    <tr><td><code>git merge-index</code></td><td>Run a merge helper for files that need merging in the index</td></tr>
    <tr><td><code>git mktag</code></td><td>Create a tag object with extra validation from stdin</td></tr>
    <tr><td><code>git mktree</code></td><td>Build a tree object from ls-tree formatted input</td></tr>
    <tr><td><code>git name-rev</code></td><td>Find symbolic names for commits: <code>git name-rev abc1234</code></td></tr>
    <tr><td><code>git cherry</code></td><td>Find commits not yet applied to upstream: <code>git cherry main</code></td></tr>
    <tr><td><code>git diff-files</code></td><td>Compare working tree to index (low-level <code>git diff</code>)</td></tr>
    <tr><td><code>git diff-index</code></td><td>Compare index to a tree object</td></tr>
    <tr><td><code>git diff-tree</code></td><td>Compare two tree objects</td></tr>
    <tr><td><code>git diff-pairs</code></td><td>Compare specific blob pairs</td></tr>
    <tr><td><code>git ls-remote</code></td><td>List refs in a remote (covered in Remotes article)</td></tr>
    <tr><td><code>git merge-base</code></td><td>Find common ancestor: <code>git merge-base main feature</code></td></tr>
    <tr><td><code>git patch-id</code></td><td>Compute a unique ID for a patch (content-based, ignores commit SHA)</td></tr>
    <tr><td><code>git stripspace</code></td><td>Remove trailing whitespace and normalize blank lines</td></tr>
    <tr><td><code>git column</code></td><td>Display data in columns (used internally by some commands)</td></tr>
    <tr><td><code>git var</code></td><td>Show Git logical variables: <code>git var GIT_AUTHOR_IDENT</code></td></tr>
    <tr><td><code>git credential</code></td><td>Retrieve and store credentials via the credential helper</td></tr>
    <tr><td><code>git check-ref-format</code></td><td>Validate a ref name: <code>git check-ref-format refs/heads/my-branch</code></td></tr>
    <tr><td><code>git fmt-merge-msg</code></td><td>Generate a merge commit message from merge heads</td></tr>
    <tr><td><code>git unpack-file</code></td><td>Create a temp file with a blob's content for external processing</td></tr>
    <tr><td><code>git pack-redundant</code></td><td>Find pack files that can be deleted (all their objects exist in other packs)</td></tr>
    <tr><td><code>git get-tar-commit-id</code></td><td>Extract the commit ID from a <code>git archive</code> tarball</td></tr>
    <tr><td><code>git replay</code></td><td>EXPERIMENTAL: replay commits on a new base in bare repos</td></tr>
    <tr><td><code>git sh-i18n</code></td><td>Git's i18n setup code for shell scripts (internal)</td></tr>
    <tr><td><code>git sh-setup</code></td><td>Common setup code used by Git's own shell scripts (internal)</td></tr>
    <tr><td><code>git lfs</code></td><td>Git Large File Storage — stores large files (binaries, media) separately from repo history (requires git-lfs extension)</td></tr>
    <tr><td><code>git jump</code></td><td>Jump to next diff, merge conflict, or grep match in your editor (requires setup)</td></tr>
  </tbody>
</table>

<h2>References</h2>
<ul>
  <li><a href="https://git-scm.com/docs/git-svn" target="_blank" rel="noopener">git-svn documentation ↗</a></li>
  <li><a href="https://git-scm.com/docs/git-send-email" target="_blank" rel="noopener">git-send-email documentation ↗</a></li>
  <li><a href="https://git-scm.com/docs/git-fast-import" target="_blank" rel="noopener">git-fast-import documentation ↗</a></li>
  <li><a href="https://git-lfs.com/" target="_blank" rel="noopener">Git LFS ↗</a></li>
</ul>
