I have not had a chance to read Oleg's PEP, but the devguide has the
reverse docs at https://docs.python.org/devguide/gitdevs.html so we have
the VCS docs down pat. :)

On Sat, Sep 12, 2015, 06:59 Oleg Broytman <p...@phdru.name> wrote:

> PEP: XXX
> Title: Collecting information about git
> Version: $Revision$
> Last-Modified: $Date$
> Author: Oleg Broytman <p...@phdru.name>
> Status: Draft
> Type: Informational
> Content-Type: text/x-rst
> Created: 01-Jun-2015
> Post-History: 12-Sep-2015
>
> Abstract
> ========
>
> This Informational PEP collects information about git. There is, of
> course, a lot of documentation for git, so the PEP concentrates on
> more complex (and more related to Python development) issues,
> scenarios and examples.
>
> The plan is to extend the PEP in the future collecting information
> about equivalence of Mercurial and git scenarios to help migrating
> Python development from Mercurial to git.
>
> The author of the PEP doesn't currently plan to write a Process PEP on
> migration Python development from Mercurial to git.
>
>
> Documentation
> =============
>
> Git is accompanied with a lot of documentation, both online and
> offline.
>
>
> Documentation for starters
> --------------------------
>
> Git Tutorial: `part 1
> <https://www.kernel.org/pub/software/scm/git/docs/gittutorial.html>`_,
> `part 2
> <https://www.kernel.org/pub/software/scm/git/docs/gittutorial-2.html>`_.
>
> `Git User's manual
> <https://www.kernel.org/pub/software/scm/git/docs/user-manual.html>`_.
> `Everyday GIT With 20 Commands Or So
> <https://www.kernel.org/pub/software/scm/git/docs/everyday.html>`_.
> `Git workflows
> <https://www.kernel.org/pub/software/scm/git/docs/gitworkflows.html>`_.
>
>
> Advanced documentation
> ----------------------
>
> `Git Magic
> <http://www-cs-students.stanford.edu/~blynn/gitmagic/index.html>`_,
> with a number of translations.
>
> `Pro Git <https://git-scm.com/book>`_. The Book about git. Buy it at
> Amazon or download in PDF, mobi, or ePub form. It has translations to
> many different languages. Download Russian translation from `GArik
> <https://github.com/GArik/progit/wiki>`_.
>
> `Git Wiki <https://git.wiki.kernel.org/index.php/Main_Page>`_.
>
>
> Offline documentation
> ---------------------
>
> Git has builtin help: run ``git help $TOPIC``. For example, run
> ``git help git`` or ``git help help``.
>
>
> Quick start
> ===========
>
> Download and installation
> -------------------------
>
> Unix users: `download and install using your package manager
> <https://git-scm.com/download/linux>`_.
>
> Microsoft Windows: download `git-for-windows
> <https://github.com/git-for-windows/git/releases>`_ or `msysGit
> <https://github.com/msysgit/msysgit/releases>`_.
>
> MacOS X: use git installed with `XCode
> <https://developer.apple.com/xcode/downloads/>`_ or download from
> `MacPorts <https://www.macports.org/ports.php?by=name&substr=git>`_ or
> `git-osx-installer
> <http://sourceforge.net/projects/git-osx-installer/files/>`_ or
> install git with `Homebrew <http://brew.sh/>`_: ``brew install git``.
>
> `git-cola <https://git-cola.github.io/index.html>`_ is a Git GUI
> written in Python and GPL licensed. Linux, Windows, MacOS X.
>
> `TortoiseGit <https://tortoisegit.org/>`_ is a Windows Shell Interface
> to Git based on TortoiseSVN; open source.
>
>
> Initial configuration
> ---------------------
>
> This simple code is often appears in documentation, but it is
> important so let repeat it here. Git stores author and committer
> names/emails in every commit, so configure your real name and
> preferred email::
>
>     $ git config --global user.name "User Name"
>     $ git config --global user.email user.n...@example.org
>
>
> Examples in this PEP
> ====================
>
> Examples of git commands in this PEP use the following approach. It is
> supposed that you, the user, works with a local repository named
> ``python`` that has an upstream remote repo named ``origin``. Your
> local repo has two branches ``v1`` and ``master``. For most examples
> the currently checked out branch is ``master``. That is, it's assumed
> you have done something like that::
>
>     $ git clone https://git.python.org/python.git
>     $ cd python
>     $ git branch v1 origin/v1
>
> The first command clones remote repository into local directory
> `python``, creates a new local branch master, sets
> remotes/origin/master as its upstream remote-tracking branch and
> checks it out into the working directory.
>
> The last command creates a new local branch v1 and sets
> remotes/origin/v1 as its upstream remote-tracking branch.
>
> The same result can be achieved with commands::
>
>     $ git clone -b v1 https://git.python.org/python.git
>     $ cd python
>     $ git checkout --track origin/master
>
> The last command creates a new local branch master, sets
> remotes/origin/master as its upstream remote-tracking branch and
> checks it out into the working directory.
>
>
> Branches and branches
> =====================
>
> Git terminology can be a bit misleading. Take, for example, the term
> "branch". In git it has two meanings. A branch is a directed line of
> commits (possibly with merges). And a branch is a label or a pointer
> assigned to a line of commits. It is important to distinguish when you
> talk about commits and when about their labels. Lines of commits are
> by itself unnamed and are usually only lengthening and merging.
> Labels, on the other hand, can be created, moved, renamed and deleted
> freely.
>
>
> Remote repositories and remote branches
> =======================================
>
> Remote-tracking branches are branches (pointers to commits) in your
> local repository. They are there for git (and for you) to remember
> what branches and commits have been pulled from and pushed to what
> remote repos (you can pull from and push to many remotes).
> Remote-tracking branches live under ``remotes/$REMOTE`` namespaces,
> e.g. ``remotes/origin/master``.
>
> To see the status of remote-tracking branches run::
>
>     $ git branch -rv
>
> To see local and remote-tracking branches (and tags) pointing to
> commits::
>
>     $ git log --decorate
>
> You never do your own development on remote-tracking branches. You
> create a local branch that has a remote branch as upstream and do
> development on that local branch. On push git pushes commits to the
> remote repo and updates remote-tracking branches, on pull git fetches
> commits from the remote repo, updates remote-tracking branches and
> fast-forwards, merges or rebases local branches.
>
> When you do an initial clone like this::
>
>     $ git clone -b v1 https://git.python.org/python.git
>
> git clones remote repository ``https://git.python.org/python.git``
> <https://git.python.org/python.git> to
> directory ``python``, creates a remote named ``origin``, creates
> remote-tracking branches, creates a local branch ``v1``, configure it
> to track upstream remotes/origin/v1 branch and checks out ``v1`` into
> the working directory.
>
>
> Updating local and remote-tracking branches
> -------------------------------------------
>
> There is a major difference between
>
> ::
>
>     $ git fetch $REMOTE $BRANCH
>
> and
>
> ::
>
>     $ git fetch $REMOTE $BRANCH:$BRANCH
>
> The first command fetches commits from the named $BRANCH in the
> $REMOTE repository that are not in your repository, updates
> remote-tracking branch and leaves the id (the hash) of the head commit
> in file .git/FETCH_HEAD.
>
> The second command fetches commits from the named $BRANCH in the
> $REMOTE repository that are not in your repository and updates both
> the local branch $BRANCH and its upstream remote-tracking branch. But
> it refuses to update branches in case of non-fast-forward. And it
> refuses to update the current branch (currently checked out branch,
> where HEAD is pointing to).
>
> The first command is used internally by ``git pull``.
>
> ::
>
>     $ git pull $REMOTE $BRANCH
>
> is equivalent to
>
> ::
>
>     $ git fetch $REMOTE $BRANCH
>     $ git merge FETCH_HEAD
>
> Certainly, $BRANCH in that case should be your current branch. If you
> want to merge a different branch into your current branch first update
> that non-current branch and then merge::
>
>     $ git fetch origin v1:v1  # Update v1
>     $ git pull --rebase origin master  # Update the current branch master
>                                        # using rebase instead of merge
>     $ git merge v1
>
> If you have not yet pushed commits on ``v1``, though, the scenario has
> to become a bit more complex. Git refuses to update
> non-fast-forwardable branch, and you don't want to do force-pull
> because that would remove your non-pushed commits and you would need
> to recover. So you want to rebase ``v1`` but you cannot rebase
> non-current branch. Hence, checkout ``v1`` and rebase it before
> merging::
>
>     $ git checkout v1
>     $ git pull --rebase origin v1
>     $ git checkout master
>     $ git pull --rebase origin master
>     $ git merge v1
>
> It is possible to configure git to make it fetch/pull a few branches
> or all branches at once, so you can simply run
>
> ::
>
>     $ git pull origin
>
> or even
>
> ::
>
>     $ git pull
>
> Default remote repository for fetching/pulling is ``origin``. Default
> set of references to fetch is calculated using matching algorithm: git
> fetches all branches having the same name on both ends.
>
>
> Push
> ''''
>
> Pushing is a bit simpler. There is only one command ``push``. When you
> run
>
> ::
>
>     $ git push origin v1 master
>
> git pushes local v1 to remote v1 and local master to remote master.
> The same as::
>
>     $ git push origin v1:v1 master:master
>
> Git pushes commits to the remote repo and updates remote-tracking
> branches. Git refuses to push commits that aren't fast-forwardable.
> You can force-push anyway, but please remember - you can force-push to
> your own repositories but don't force-push to public or shared repos.
> If you find git refuses to push commits that aren't fast-forwardable,
> better fetch and merge commits from the remote repo (or rebase your
> commits on top of the fetched commits), then push. Only force-push if
> you know what you do and why you do it. See the section `Commit
> editing and caveats`_ below.
>
> It is possible to configure git to make it push a few branches or all
> branches at once, so you can simply run
>
> ::
>
>     $ git push origin
>
> or even
>
> ::
>
>     $ git push
>
> Default remote repository for pushing is ``origin``. Default set of
> references to push in git before 2.0 is calculated using matching
> algorithm: git pushes all branches having the same name on both ends.
> Default set of references to push in git 2.0+ is calculated using
> simple algorithm: git pushes the current branch back to its
> @{upstream}.
>
> To configure git before 2.0 to the new behaviour run::
>
> $ git config push.default simple
>
> To configure git 2.0+ to the old behaviour run::
>
> $ git config push.default matching
>
> Git doesn't allow to push a branch if it's the current branch in the
> remote non-bare repository: git refuses to update remote working
> directory. You really should push only to bare repositories. For
> non-bare repositories git prefers pull-based workflow.
>
> When you want to deploy code on a remote host and can only use push
> (because your workstation is behind a firewall and you cannot pull
> from it) you do that in two steps using two repositories: you push
> from the workstation to a bare repo on the remote host, ssh to the
> remote host and pull from the bare repo to a non-bare deployment repo.
>
> That changed in git 2.3, but see `the blog post
> <https://github.com/blog/1957-git-2-3-has-been-released#push-to-deploy>`_
> for caveats; in 2.4 the push-to-deploy feature was `further improved
> <
> https://github.com/blog/1994-git-2-4-atomic-pushes-push-to-deploy-and-more#push-to-deploy-improvements
> >`_.
>
>
> Tags
> ''''
>
> Git automatically fetches tags that point to commits being fetched
> during fetch/pull. To fetch all tags (and commits they point to) run
> ``git fetch --tags origin``. To fetch some specific tags fetch them
> explicitly::
>
>     $ git fetch origin tag $TAG1 tag $TAG2...
>
> For example::
>
>     $ git fetch origin tag 1.4.2
>     $ git fetch origin v1:v1 tag 2.1.7
>
> Git doesn't automatically pushes tags. That allows you to have private
> tags. To push tags list them explicitly::
>
>     $ git push origin tag 1.4.2
>     $ git push origin v1 master tag 2.1.7
>
> Or push all tags at once::
>
>     $ git push --tags origin
>
> Don't move tags with ``git tag -f`` or remove tags with ``git tag -d``
> after they have been published.
>
>
> Private information
> '''''''''''''''''''
>
> When cloning/fetching/pulling/pushing git copies only database objects
> (commits, trees, files and tags) and symbolic references (branches and
> lightweight tags). Everything else is private to the repository and
> never cloned, updated or pushed. It's your config, your hooks, your
> private exclude file.
>
> If you want to distribute hooks, copy them to the working tree, add,
> commit, push and instruct the team to update and install the hooks
> manually.
>
>
> Commit editing and caveats
> ==========================
>
> A warning not to edit published (pushed) commits also appears in
> documentation but it's repeated here anyway as it's very important.
>
> It is possible to recover from a forced push but it's PITA for the
> entire team. Please avoid it.
>
> To see what commits have not been published yet compare the head of the
> branch with its upstream remote-tracking branch::
>
>     $ git log origin/master..  # from origin/master to HEAD (of master)
>     $ git log origin/v1..v1  # from origin/v1 to the head of v1
>
> For every branch that has an upstream remote-tracking branch git
> maintains an alias @{upstream} (short version @{u}), so the commands
> above can be given as::
>
>     $ git log @{u}..
>     $ git log v1@{u}..v1
>
> To see the status of all branches::
>
>     $ git branch -avv
>
> To compare the status of local branches with a remote repo::
>
>     $ git remote show origin
>
> Read `how to recover from upstream rebase
> <https://git-scm.com/docs/git-rebase#_recovering_from_upstream_rebase>`_.
> It is in ``git help rebase``.
>
> On the other hand don't be too afraid about commit editing. You can
> safely edit, reorder, remove, combine and split commits that haven't
> been pushed yet. You can even push commits to your own (backup) repo,
> edit them later and force-push edited commits to replace what have
> already been pushed. Not a problem until commits are in a public
> or shared repository.
>
>
> Undo
> ====
>
> Whatever you do, don't panic. Almost anything in git can be undone.
>
>
> git checkout: restore file's content
> ------------------------------------
>
> ``git checkout``, for example, can be used to restore the content of
> file(s) to that one of a commit. Like this::
>
>     git checkout HEAD~ README
>
> The commands restores the contents of README file to the last but one
> commit in the current branch. By default the commit ID is simply HEAD;
> i.e. ``git checkout README`` restores README to the latest commit.
>
> (Do not use ``git checkout`` to view a content of a file in a commit,
> use ``git cat-file -p``; e.g. ``git cat-file -p HEAD~:path/to/README``).
>
>
> git reset: remove (non-pushed) commits
> --------------------------------------
>
> ``git reset`` moves the head of the current branch. The head can be
> moved to point to any commit but it's often used to remove a commit or
> a few (preferably, non-pushed ones) from the top of the branch - that
> is, to move the branch backward in order to undo a few (non-pushed)
> commits.
>
> ``git reset`` has three modes of operation - soft, hard and mixed.
> Default is mixed. ProGit `explains
> <https://git-scm.com/book/en/Git-Tools-Reset-Demystified>`_ the
> difference very clearly. Bare repositories don't have indices or
> working trees so in a bare repo only soft reset is possible.
>
>
> Unstaging
> '''''''''
>
> Mixed mode reset with a path or paths can be used to unstage changes -
> that is, to remove from index changes added with ``git add`` for
> committing. See `The Book
> <https://git-scm.com/book/en/Git-Basics-Undoing-Things>`_ for details
> about unstaging and other undo tricks.
>
>
> git reflog: reference log
> -------------------------
>
> Removing commits with ``git reset`` or moving the head of a branch
> sounds dangerous and it is. But there is a way to undo: another
> reset back to the original commit. Git doesn't remove commits
> immediately; unreferenced commits (in git terminology they are called
> "dangling commits") stay in the database for some time (default is two
> weeks) so you can reset back to it or create a new branch pointing to
> the original commit.
>
> For every move of a branch's head - with ``git commit``, ``git
> checkout``, ``git fetch``, ``git pull``, ``git rebase``, ``git reset``
> and so on - git stores a reference log (reflog for short). For every
> move git stores where the head was. Command ``git reflog`` can be used
> to view (and manipulate) the log.
>
> In addition to the moves of the head of every branch git stores the
> moves of the HEAD - a symbolic reference that (usually) names the
> current branch. HEAD is changed with ``git checkout $BRANCH``.
>
> By default ``git reflog`` shows the moves of the HEAD, i.e. the
> command is equivalent to ``git reflog HEAD``. To show the moves of the
> head of a branch use the command ``git reflog $BRANCH``.
>
> So to undo a ``git reset`` lookup the original commit in ``git
> reflog``, verify it with ``git show`` or ``git log`` and run ``git
> reset $COMMIT_ID``. Git stores the move of the branch's head in
> reflog, so you can undo that undo later again.
>
> In a more complex situation you'd want to move some commits along with
> resetting the head of the branch. Cherry-pick them to the new branch.
> For example, if you want to reset the branch ``master`` back to the
> original commit but preserve two commits created in the current branch
> do something like::
>
>     $ git branch save-master # create a new branch saving master
>     $ git reflog # find the original place of master
>     $ git reset $COMMIT_ID
>     $ git cherry-pick save-master~ save-master
>     $ git branch -D save-master # remove temporary branch
>
>
> git revert: revert a commit
> ---------------------------
>
> ``git revert`` reverts a commit or commits, that is, it creates a new
> commit or commits that revert(s) the effects of the given commits.
> It's the only way to undo published commits (``git commit --amend``,
> ``git rebase`` and ``git reset`` change the branch in
> non-fast-forwardable ways so they should only be used for non-pushed
> commits.)
>
> There is a problem with reverting a merge commit. ``git revert`` can
> undo the code created by the merge commit but it cannot undo the fact
> of merge. See the discussion `How to revert a faulty merge
> <
> https://www.kernel.org/pub/software/scm/git/docs/howto/revert-a-faulty-merge.html
> >`_.
>
>
> One thing that cannot be undone
> -------------------------------
>
> Whatever you undo, there is one thing that cannot be undone -
> overwritten uncommitted changes. Uncommitted changes don't belong to
> git so git cannot help preserving them.
>
> Most of the time git warns you when you're going to execute a command
> that overwrites uncommitted changes. Git doesn't allow you to switch
> branches with ``git checkout``. It stops you when you're going to
> rebase with non-clean working tree. It refuses to pull new commits
> over non-committed files.
>
> But there are commands that do exactly that - overwrite files in the
> working tree. Commands like ``git checkout $PATHs`` or ``git reset
> --hard`` silently overwrite files including your uncommitted changes.
>
> With that in mind you can understand the stance "commit early, commit
> often". Commit as often as possible. Commit on every save in your
> editor or IDE. You can edit your commits before pushing - edit commit
> messages, change commits, reorder, combine, split, remove. But save
> your changes in git database, either commit changes or at least stash
> them with ``git stash``.
>
>
> Merge or rebase?
> ================
>
> Internet is full of heated discussions on the topic: "merge or
> rebase?" Most of them are meaningless. When a DVCS is being used in a
> big team with a big and complex project with many branches there is
> simply no way to avoid merges. So the question's diminished to
> "whether to use rebase, and if yes - when to use rebase?" Considering
> that it is very much recommended not to rebase published commits the
> question's diminished even further: "whether to use rebase on
> non-pushed commits?"
>
> That small question is for the team to decide. The author of the PEP
> recommends to use rebase when pulling, i.e. always do ``git pull
> --rebase`` or even configure automatic setup of rebase for every new
> branch::
>
>     $ git config branch.autosetuprebase always
>
> and configure rebase for existing branches::
>
>     $ git config branch.$NAME.rebase true
>
> For example::
>
>     $ git config branch.v1.rebase true
>     $ git config branch.master.rebase true
>
> After that ``git pull origin master`` becomes equivalent to ``git pull
> --rebase origin master``.
>
> It is recommended to create new commits in a separate feature or topic
> branch while using rebase to update the mainline branch. When the
> topic branch is ready merge it into mainline. To avoid a tedious task
> of resolving large number of conflicts at once you can merge the topic
> branch to the mainline from time to time and switch back to the topic
> branch to continue working on it. The entire workflow would be
> something like::
>
>     $ git checkout -b issue-42  # create a new issue branch and switch to
> it
>         ...edit/test/commit...
>     $ git checkout master
>     $ git pull --rebase origin master  # update master from the upstream
>     $ git merge issue-42
>     $ git branch -d issue-42  # delete the topic branch
>     $ git push origin master
>
> When the topic branch is deleted only the label is removed, commits
> are stayed in the database, they are now merged into master::
>
>     o--o--o--o--o--M--< master - the mainline branch
>         \         /
>          --*--*--*             - the topic branch, now unnamed
>
> The topic branch is deleted to avoid cluttering branch namespace with
> small topic branches. Information on what issue was fixed or what
> feature was implemented should be in the commit messages.
>
>
> Null-merges
> ===========
>
> Git has a builtin merge strategy for what Python core developers call
> "null-merge"::
>
>     $ git merge -s ours v1  # null-merge v1 into master
>
>
> Advanced configuration
> ======================
>
> Line endings
> ------------
>
> Git has builtin mechanisms to handle line endings between platforms
> with different end-of-line styles. To allow git to do CRLF conversion
> assign ``text`` attribute to files using `.gitattributes
> <https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html>`_.
> For files that have to have specific line endings assign ``eol``
> attribute. For binary files the attribute is, naturally, ``binary``.
>
> For example::
>
>     $ cat .gitattributes
>     *.py text
>     *.txt text
>     *.png binary
>     /readme.txt eol=CRLF
>
> To check what attributes git uses for files use ``git check-attr``
> command. For example::
>
> $ git check-attr -a -- \*.py
>
>
> Advanced topics
> ===============
>
> Staging area
> ------------
>
> Staging area aka index aka cache is a distinguishing feature of git.
> Staging area is where git collects patches before committing them.
> Separation between collecting patches and commit phases provides a
> very useful feature of git: you can review collected patches before
> commit and even edit them - remove some hunks, add new hunks and
> review again.
>
> To add files to the index use ``git add``. Collecting patches before
> committing means you need to do that for every change, not only to add
> new (untracked) files. To simplify committing in case you just want to
> commit everything without reviewing run ``git commit --all`` (or just
> ``-a``) - the command adds every changed tracked file to the index and
> then commit. To commit a file or files regardless of patches collected
> in the index run ``git commit [--only|-o] -- $FILE...``.
>
> To add hunks of patches to the index use ``git add --patch`` (or just
> ``-p``). To remove collected files from the index use ``git reset HEAD
> -- $FILE...`` To add/inspect/remove collected hunks use ``git add
> --interactive`` (``-i``).
>
> To see the diff between the index and the last commit (i.e., collected
> patches) use ``git diff --cached``. To see the diff between the
> working tree and the index (i.e., uncollected patches) use just ``git
> diff``. To see the diff between the working tree and the last commit
> (i.e., both collected and uncollected patches) run ``git diff HEAD``.
>
> See `WhatIsTheIndex
> <https://git.wiki.kernel.org/index.php/WhatIsTheIndex>`_ and
> `IndexCommandQuickref
> <https://git.wiki.kernel.org/index.php/IndexCommandQuickref>`_ in Git
> Wiki.
>
>
> ReReRe
> ======
>
> Rerere is a mechanism that helps to resolve repeated merge conflicts.
> The most frequent source of recurring merge conflicts are topic
> branches that are merged into mainline and then the merge commits are
> removed; that's often performed to test the topic branches and train
> rerere; merge commits are removed to have clean linear history and
> finish the topic branch with only one last merge commit.
>
> Rerere works by remembering the states of tree before and after a
> successful commit. That way rerere can automatically resolve conflicts
> if they appear in the same files.
>
> Rerere can be used manually with ``git rerere`` command but most often
> it's used automatically. Enable rerere with these commands in a
> working tree::
>
>     $ git config rerere.enabled true
>     $ git config rerere.autoupdate true
>
> You don't need to turn rerere on globally - you don't want rerere in
> bare repositories or single-branche repositories; you only need rerere
> in repos where you often perform merges and resolve merge conflicts.
>
> See `Rerere <https://git-scm.com/book/en/Git-Tools-Rerere>`_ in The
> Book.
>
>
> Database maintenance
> ====================
>
> Git object database and other files/directories under ``.git`` require
> periodic maintenance and cleanup. For example, commit editing left
> unreferenced objects (dangling objects, in git terminology) and these
> objects should be pruned to avoid collecting cruft in the DB. The
> command ``git gc`` is used for maintenance. Git automatically runs
> ``git gc --auto`` as a part of some commands to do quick maintenance.
> Users are recommended to run ``git gc --aggressive`` from time to
> time; ``git help gc`` recommends to run it  every few hundred
> changesets; for more intensive projects it should be something like
> once a week and less frequently (biweekly or monthly) for lesser
> active projects.
>
> ``git gc --aggressive`` not only removes dangling objects, it also
> repacks object database into indexed and better optimized pack(s); it
> also packs symbolic references (branches and tags). Another way to do
> it is to run ``git repack``.
>
> There is a well-known `message
> <https://gcc.gnu.org/ml/gcc/2007-12/msg00165.html>`_ from Linus
> Torvalds regarding "stupidity" of ``git gc --aggressive``. The message
> can safely be ignored now. It is old and outdated, ``git gc
> --aggressive`` became much better since that time.
>
> For those who still prefer ``git repack`` over ``git gc --aggressive``
> the recommended parameters are ``git repack -a -d -f --depth=20
> --window=250``. See `this detailed experiment
> <http://vcscompare.blogspot.ru/2008/06/git-repack-parameters.html>`_
> for explanation of the effects of these parameters.
>
> From time to time run ``git fsck [--strict]`` to verify integrity of
> the database. ``git fsck`` may produce a list of dangling objects;
> that's not an error, just a reminder to perform regular maintenance.
>
>
> Tips and tricks
> ===============
>
> Command-line options and arguments
> ----------------------------------
>
> `git help cli
> <https://www.kernel.org/pub/software/scm/git/docs/gitcli.html>`_
> recommends not to combine short options/flags. Most of the times
> combining works: ``git commit -av`` works perfectly, but there are
> situations when it doesn't. E.g., ``git log -p -5`` cannot be combined
> as ``git log -p5``.
>
> Some options have arguments, some even have default arguments. In that
> case the argument for such option must be spelled in a sticky way:
> ``-Oarg``, never ``-O arg`` because for an option that has a default
> argument the latter means "use default value for option ``-O`` and
> pass ``arg`` further to the option parser". For example, ``git grep``
> has an option ``-O`` that passes a list of names of the found files to
> a program; default program for ``-O`` is a pager (usually ``less``),
> but you can use your editor::
>
>     $ git grep -Ovim # but not -O vim
>
> BTW, if git is instructed to use ``less`` as the pager (i.e., if pager
> is not configured in git at all it uses ``less`` by default, or if it
> gets ``less`` from GIT_PAGER or PAGER environment variables, or if it
> was configured with ``git config --global core.pager less``, or
> ``less`` is used in the command ``git grep -Oless``) ``git grep``
> passes ``+/$pattern`` option to ``less`` which is quite convenient.
> Unfortunately, ``git grep`` doesn't pass the pattern if the pager is
> not exactly ``less``, even if it's ``less`` with parameters (something
> like ``git config --global core.pager less -FRSXgimq``); fortunately,
> ``git grep -Oless`` always passes the pattern.
>
>
> bash/zsh completion
> -------------------
>
> It's a bit hard to type ``git rebase --interactive --preserve-merges
> HEAD~5`` manually even for those who are happy to use command-line,
> and this is where shell completion is of great help. Bash/zsh come
> with programmable completion, often automatically installed and
> enabled, so if you have bash/zsh and git installed, chances are you
> are already done - just go and use it at the command-line.
>
> If you don't have necessary bits installed, install and enable
> bash_completion package. If you want to upgrade your git completion to
> the latest and greatest download necessary file from `git contrib
> <https://git.kernel.org/cgit/git/git.git/tree/contrib/completion>`_.
>
> Git-for-windows comes with git-bash for which bash completion is
> installed and enabled.
>
>
> bash/zsh prompt
> ---------------
>
> For command-line lovers shell prompt can carry a lot of useful
> information. To include git information in the prompt use
> `git-prompt.sh
> <
> https://git.kernel.org/cgit/git/git.git/tree/contrib/completion/git-prompt.sh
> >`_.
> Read the detailed instructions in the file.
>
> Search the Net for "git prompt" to find other prompt variants.
>
>
> git on server
> =============
>
> The simplest way to publish a repository or a group of repositories is
> ``git daemon``. The daemon provides anonymous access, by default it is
> read-only. The repositories are accessible by git protocol (git://
> URLs). Write access can be enabled but the protocol lacks any
> authentication means, so it should be enabled only within a trusted
> LAN. See ``git help daemon`` for details.
>
> Git over ssh provides authentication and repo-level authorisation as
> repositories can be made user- or group-writeable (see parameter
> ``core.sharedRepository`` in ``git help config``). If that's too
> permissive or too restrictive for some project's needs there is a
> wrapper `gitolite <http://gitolite.com/gitolite/index.html>`_ that can
> be configured to allow access with great granularity; gitolite is
> written in Perl and has a lot of documentation.
>
> Web interface to browse repositories can be created using `gitweb
> <https://git.kernel.org/cgit/git/git.git/tree/gitweb>`_ or `cgit
> <http://git.zx2c4.com/cgit/about/>`_. Both are CGI scripts (written in
> Perl and C). In addition to web interface both provide read-only dumb
> http access for git (http(s):// URLs).
>
> There are also more advanced web-based development environments that
> include ability to manage users, groups and projects; private,
> group-accessible and public repositories; they often include issue
> trackers, wiki pages, pull requests and other tools for development
> and communication. Among these environments are `Kallithea
> <https://kallithea-scm.org/>`_ and `pagure <https://pagure.io/>`_,
> both are written in Python; pagure was written by Fedora developers
> and is being used to develop some Fedora projects. `Gogs
> <http://gogs.io/>`_ is written in Go; there is a fork `Gitea
> <http://gitea.io/>`_.
>
> And last but not least, `Gitlab <https://about.gitlab.com/>`_. It's
> perhaps the most advanced web-based development environment for git.
> Written in Ruby, community edition is free and open source (MIT
> license).
>
>
> From Mercurial to git
> =====================
>
> There are many tools to convert Mercurial repositories to git. The
> most famous are, probably, `hg-git <https://hg-git.github.io/>`_ and
> `fast-export <http://repo.or.cz/w/fast-export.git>`_ (many years ago
> it was known under the name ``hg2git``).
>
> But a better tool, perhaps the best, is `git-remote-hg
> <https://github.com/felipec/git-remote-hg>`_. It provides transparent
> bidirectional (pull and push) access to Mercurial repositories from
> git. Its author wrote a `comparison of alternatives
> <
> https://github.com/felipec/git/wiki/Comparison-of-git-remote-hg-alternatives
> >`_
> that seems to be mostly objective.
>
> To use git-remote-hg, install or clone it, add to your PATH (or copy
> script ``git-remote-hg`` to a directory that's already in PATH) and
> prepend ``hg::`` to Mercurial URLs. For example::
>
>     $ git clone https://github.com/felipec/git-remote-hg.git
>     $ PATH=$PATH:"`pwd`"/git-remote-hg
>     $ git clone hg::https://hg.python.org/peps/ PEPs
>
> To work with the repository just use regular git commands including
> ``git fetch/pull/push``.
>
> To start converting your Mercurial habits to git see the page
> `Mercurial for Git users
> <https://mercurial.selenic.com/wiki/GitConcepts>`_ at Mercurial wiki.
> At the second half of the page there is a table that lists
> corresponding Mercurial and git commands. Should work perfectly in
> both directions.
>
>
> Copyright
> =========
>
> This document has been placed in the public domain.
>
>
>
> ..
>    Local Variables:
>    mode: indented-text
>    indent-tabs-mode: nil
>    sentence-end-double-space: t
>    fill-column: 70
>    coding: utf-8
>    End:
>    vim: set fenc=us-ascii tw=70 :
> _______________________________________________
> Python-Dev mailing list
> Python-Dev@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> https://mail.python.org/mailman/options/python-dev/brett%40python.org
>
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to