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