yading@10: \input texinfo @c -*- texinfo -*- yading@10: yading@10: @settitle Using git to develop FFmpeg yading@10: yading@10: @titlepage yading@10: @center @titlefont{Using git to develop FFmpeg} yading@10: @end titlepage yading@10: yading@10: @top yading@10: yading@10: @contents yading@10: yading@10: @chapter Introduction yading@10: yading@10: This document aims in giving some quick references on a set of useful git yading@10: commands. You should always use the extensive and detailed documentation yading@10: provided directly by git: yading@10: yading@10: @example yading@10: git --help yading@10: man git yading@10: @end example yading@10: yading@10: shows you the available subcommands, yading@10: yading@10: @example yading@10: git --help yading@10: man git- yading@10: @end example yading@10: yading@10: shows information about the subcommand . yading@10: yading@10: Additional information could be found on the yading@10: @url{http://gitref.org, Git Reference} website yading@10: yading@10: For more information about the Git project, visit the yading@10: yading@10: @url{http://git-scm.com/, Git website} yading@10: yading@10: Consult these resources whenever you have problems, they are quite exhaustive. yading@10: yading@10: What follows now is a basic introduction to Git and some FFmpeg-specific yading@10: guidelines to ease the contribution to the project yading@10: yading@10: @chapter Basics Usage yading@10: yading@10: @section Get GIT yading@10: yading@10: You can get git from @url{http://git-scm.com/} yading@10: Most distribution and operating system provide a package for it. yading@10: yading@10: yading@10: @section Cloning the source tree yading@10: yading@10: @example yading@10: git clone git://source.ffmpeg.org/ffmpeg yading@10: @end example yading@10: yading@10: This will put the FFmpeg sources into the directory @var{}. yading@10: yading@10: @example yading@10: git clone git@@source.ffmpeg.org:ffmpeg yading@10: @end example yading@10: yading@10: This will put the FFmpeg sources into the directory @var{} and let yading@10: you push back your changes to the remote repository. yading@10: yading@10: Make sure that you do not have Windows line endings in your checkouts, yading@10: otherwise you may experience spurious compilation failures. One way to yading@10: achieve this is to run yading@10: yading@10: @example yading@10: git config --global core.autocrlf false yading@10: @end example yading@10: yading@10: yading@10: @section Updating the source tree to the latest revision yading@10: yading@10: @example yading@10: git pull (--rebase) yading@10: @end example yading@10: yading@10: pulls in the latest changes from the tracked branch. The tracked branch yading@10: can be remote. By default the master branch tracks the branch master in yading@10: the remote origin. yading@10: yading@10: @float IMPORTANT yading@10: @command{--rebase} (see below) is recommended. yading@10: @end float yading@10: yading@10: @section Rebasing your local branches yading@10: yading@10: @example yading@10: git pull --rebase yading@10: @end example yading@10: yading@10: fetches the changes from the main repository and replays your local commits yading@10: over it. This is required to keep all your local changes at the top of yading@10: FFmpeg's master tree. The master tree will reject pushes with merge commits. yading@10: yading@10: yading@10: @section Adding/removing files/directories yading@10: yading@10: @example yading@10: git add [-A] yading@10: git rm [-r] yading@10: @end example yading@10: yading@10: GIT needs to get notified of all changes you make to your working yading@10: directory that makes files appear or disappear. yading@10: Line moves across files are automatically tracked. yading@10: yading@10: yading@10: @section Showing modifications yading@10: yading@10: @example yading@10: git diff yading@10: @end example yading@10: yading@10: will show all local modifications in your working directory as unified diff. yading@10: yading@10: yading@10: @section Inspecting the changelog yading@10: yading@10: @example yading@10: git log yading@10: @end example yading@10: yading@10: You may also use the graphical tools like gitview or gitk or the web yading@10: interface available at http://source.ffmpeg.org/ yading@10: yading@10: @section Checking source tree status yading@10: yading@10: @example yading@10: git status yading@10: @end example yading@10: yading@10: detects all the changes you made and lists what actions will be taken in case yading@10: of a commit (additions, modifications, deletions, etc.). yading@10: yading@10: yading@10: @section Committing yading@10: yading@10: @example yading@10: git diff --check yading@10: @end example yading@10: yading@10: to double check your changes before committing them to avoid trouble later yading@10: on. All experienced developers do this on each and every commit, no matter yading@10: how small. yading@10: Every one of them has been saved from looking like a fool by this many times. yading@10: It's very easy for stray debug output or cosmetic modifications to slip in, yading@10: please avoid problems through this extra level of scrutiny. yading@10: yading@10: For cosmetics-only commits you should get (almost) empty output from yading@10: yading@10: @example yading@10: git diff -w -b yading@10: @end example yading@10: yading@10: Also check the output of yading@10: yading@10: @example yading@10: git status yading@10: @end example yading@10: yading@10: to make sure you don't have untracked files or deletions. yading@10: yading@10: @example yading@10: git add [-i|-p|-A] yading@10: @end example yading@10: yading@10: Make sure you have told git your name and email address yading@10: yading@10: @example yading@10: git config --global user.name "My Name" yading@10: git config --global user.email my@@email.invalid yading@10: @end example yading@10: yading@10: Use @var{--global} to set the global configuration for all your git checkouts. yading@10: yading@10: Git will select the changes to the files for commit. Optionally you can use yading@10: the interactive or the patch mode to select hunk by hunk what should be yading@10: added to the commit. yading@10: yading@10: yading@10: @example yading@10: git commit yading@10: @end example yading@10: yading@10: Git will commit the selected changes to your current local branch. yading@10: yading@10: You will be prompted for a log message in an editor, which is either yading@10: set in your personal configuration file through yading@10: yading@10: @example yading@10: git config --global core.editor yading@10: @end example yading@10: yading@10: or set by one of the following environment variables: yading@10: @var{GIT_EDITOR}, @var{VISUAL} or @var{EDITOR}. yading@10: yading@10: Log messages should be concise but descriptive. Explain why you made a change, yading@10: what you did will be obvious from the changes themselves most of the time. yading@10: Saying just "bug fix" or "10l" is bad. Remember that people of varying skill yading@10: levels look at and educate themselves while reading through your code. Don't yading@10: include filenames in log messages, Git provides that information. yading@10: yading@10: Possibly make the commit message have a terse, descriptive first line, an yading@10: empty line and then a full description. The first line will be used to name yading@10: the patch by git format-patch. yading@10: yading@10: @section Preparing a patchset yading@10: yading@10: @example yading@10: git format-patch [-o directory] yading@10: @end example yading@10: yading@10: will generate a set of patches for each commit between @var{} and yading@10: current @var{HEAD}. E.g. yading@10: yading@10: @example yading@10: git format-patch origin/master yading@10: @end example yading@10: yading@10: will generate patches for all commits on current branch which are not yading@10: present in upstream. yading@10: A useful shortcut is also yading@10: yading@10: @example yading@10: git format-patch -n yading@10: @end example yading@10: yading@10: which will generate patches from last @var{n} commits. yading@10: By default the patches are created in the current directory. yading@10: yading@10: @section Sending patches for review yading@10: yading@10: @example yading@10: git send-email yading@10: @end example yading@10: yading@10: will send the patches created by @command{git format-patch} or directly yading@10: generates them. All the email fields can be configured in the global/local yading@10: configuration or overridden by command line. yading@10: Note that this tool must often be installed separately (e.g. @var{git-email} yading@10: package on Debian-based distros). yading@10: yading@10: yading@10: @section Renaming/moving/copying files or contents of files yading@10: yading@10: Git automatically tracks such changes, making those normal commits. yading@10: yading@10: @example yading@10: mv/cp path/file otherpath/otherfile yading@10: git add [-A] . yading@10: git commit yading@10: @end example yading@10: yading@10: yading@10: @chapter Git configuration yading@10: yading@10: In order to simplify a few workflows, it is advisable to configure both yading@10: your personal Git installation and your local FFmpeg repository. yading@10: yading@10: @section Personal Git installation yading@10: yading@10: Add the following to your @file{~/.gitconfig} to help @command{git send-email} yading@10: and @command{git format-patch} detect renames: yading@10: yading@10: @example yading@10: [diff] yading@10: renames = copy yading@10: @end example yading@10: yading@10: @section Repository configuration yading@10: yading@10: In order to have @command{git send-email} automatically send patches yading@10: to the ffmpeg-devel mailing list, add the following stanza yading@10: to @file{/path/to/ffmpeg/repository/.git/config}: yading@10: yading@10: @example yading@10: [sendemail] yading@10: to = ffmpeg-devel@@ffmpeg.org yading@10: @end example yading@10: yading@10: @chapter FFmpeg specific yading@10: yading@10: @section Reverting broken commits yading@10: yading@10: @example yading@10: git reset yading@10: @end example yading@10: yading@10: @command{git reset} will uncommit the changes till @var{} rewriting yading@10: the current branch history. yading@10: yading@10: @example yading@10: git commit --amend yading@10: @end example yading@10: yading@10: allows to amend the last commit details quickly. yading@10: yading@10: @example yading@10: git rebase -i origin/master yading@10: @end example yading@10: yading@10: will replay local commits over the main repository allowing to edit, merge yading@10: or remove some of them in the process. yading@10: yading@10: @float NOTE yading@10: @command{git reset}, @command{git commit --amend} and @command{git rebase} yading@10: rewrite history, so you should use them ONLY on your local or topic branches. yading@10: The main repository will reject those changes. yading@10: @end float yading@10: yading@10: @example yading@10: git revert yading@10: @end example yading@10: yading@10: @command{git revert} will generate a revert commit. This will not make the yading@10: faulty commit disappear from the history. yading@10: yading@10: @section Pushing changes to remote trees yading@10: yading@10: @example yading@10: git push yading@10: @end example yading@10: yading@10: Will push the changes to the default remote (@var{origin}). yading@10: Git will prevent you from pushing changes if the local and remote trees are yading@10: out of sync. Refer to and to sync the local tree. yading@10: yading@10: @example yading@10: git remote add yading@10: @end example yading@10: yading@10: Will add additional remote with a name reference, it is useful if you want yading@10: to push your local branch for review on a remote host. yading@10: yading@10: @example yading@10: git push yading@10: @end example yading@10: yading@10: Will push the changes to the @var{} repository. yading@10: Omitting @var{} makes @command{git push} update all the remote yading@10: branches matching the local ones. yading@10: yading@10: @section Finding a specific svn revision yading@10: yading@10: Since version 1.7.1 git supports @var{:/foo} syntax for specifying commits yading@10: based on a regular expression. see man gitrevisions yading@10: yading@10: @example yading@10: git show :/'as revision 23456' yading@10: @end example yading@10: yading@10: will show the svn changeset @var{r23456}. With older git versions searching in yading@10: the @command{git log} output is the easiest option (especially if a pager with yading@10: search capabilities is used). yading@10: This commit can be checked out with yading@10: yading@10: @example yading@10: git checkout -b svn_23456 :/'as revision 23456' yading@10: @end example yading@10: yading@10: or for git < 1.7.1 with yading@10: yading@10: @example yading@10: git checkout -b svn_23456 $SHA1 yading@10: @end example yading@10: yading@10: where @var{$SHA1} is the commit hash from the @command{git log} output. yading@10: yading@10: yading@10: @chapter pre-push checklist yading@10: yading@10: Once you have a set of commits that you feel are ready for pushing, yading@10: work through the following checklist to doublecheck everything is in yading@10: proper order. This list tries to be exhaustive. In case you are just yading@10: pushing a typo in a comment, some of the steps may be unnecessary. yading@10: Apply your common sense, but if in doubt, err on the side of caution. yading@10: yading@10: First, make sure that the commits and branches you are going to push yading@10: match what you want pushed and that nothing is missing, extraneous or yading@10: wrong. You can see what will be pushed by running the git push command yading@10: with --dry-run first. And then inspecting the commits listed with yading@10: @command{git log -p 1234567..987654}. The @command{git status} command yading@10: may help in finding local changes that have been forgotten to be added. yading@10: yading@10: Next let the code pass through a full run of our testsuite. yading@10: yading@10: @itemize yading@10: @item @command{make distclean} yading@10: @item @command{/path/to/ffmpeg/configure} yading@10: @item @command{make check} yading@10: @item if fate fails due to missing samples run @command{make fate-rsync} and retry yading@10: @end itemize yading@10: yading@10: Make sure all your changes have been checked before pushing them, the yading@10: testsuite only checks against regressions and that only to some extend. It does yading@10: obviously not check newly added features/code to be working unless you have yading@10: added a test for that (which is recommended). yading@10: yading@10: Also note that every single commit should pass the test suite, not just yading@10: the result of a series of patches. yading@10: yading@10: Once everything passed, push the changes to your public ffmpeg clone and post a yading@10: merge request to ffmpeg-devel. You can also push them directly but this is not yading@10: recommended. yading@10: yading@10: @chapter Server Issues yading@10: yading@10: Contact the project admins @email{root@@ffmpeg.org} if you have technical yading@10: problems with the GIT server.