1# $FreeBSD$ 2 3This directory contains tools intended to help committers use git when 4interacting with standard FreeBSD project resources like Differential or svn. 5 6I. arcgit 7 8arcgit is a wrapper script around the arc command line tool that simplifies the 9automatic creation of a series of Differential reviews from a series of git 10commits. The intended workflow is: 11 121. Create a series of commits in git. Each commit will be a separate review, so 13 try to make each commit as self-contained as possible. The series of commits 14 should demonstrate a logical progression towards your end goal. For example, 15 one commit might refactor existing code to expose a new API without changing 16 any current functionality. A subsequent commit could then introduce your new 17 code that uses the new API. 18 19 It usually will not be helpful to present your code in the order in which it 20 was actually written and can actually be harmful. For example, if you 21 introduced a bug early in your development process that you fixed in a 22 subsequent commit, it is a waste of your reviewer's time to have them review 23 old code with known bugs. Instead, it would probably be best to squash the 24 bug fix into the commit that introduced it, so that the bug is never 25 presented to your reviewers in any review. 26 27 The commit headline and commit message will be imported verbatim into 28 Differential, so try to give each commit a meaningful commit message that 29 gives your reviewers the necessary context to understand your change. 30 312. Create your reviews bu running this command in your git repo: 32 $ arcgit -r C1~..C2 -R reviewer -T testplan 33 34 C1 should be the first commit that you want reviewed, and C2 should be the 35 last commit that you want reviewed. You may add multiple reviewers by 36 specifying the -R option multiple times. You can CC (AKA subscribe) people 37 to a review with the -C option. Note that if you subscribe a mailing list 38 to a review, the mailing list will be emailed for every comment or change 39 made to each review. Please be judicious when subscibing mailing lists to 40 reviews. It may be better to instead send a single email to the appropriate 41 list announcing all of the reviews and giving a short summary of the change 42 as a whole, along with a link to the individual reviews. 43 443. When you need to make a change and upload it to a review, use the following 45 process. First, check out the branch corresponding to the review (arcgit 46 automatically creates this branch for every review that it creates): 47 48 $ git checkout review_D1234 49 50 Next, make your change and perform whatever testing is necessary. Commit it 51 to your repository with this command: 52 53 $ git commit --fixup HEAD 54 55 You can upload the change to the code review by running this command in your 56 repository while (ensure that you are still on the review_D1234 branch): 57 58 $ arc diff --update D1234 review_D1234_base 59 60 When you run arc, it will pull up your editor and give you a chance to 61 change the message that will be shown in Differential for this upload. It's 62 recommended that you change it from the default "fixup! ...." as that does 63 not give your reviewers an indication of what changes were made. It's not 64 recommended that you give the code review fixes meaningful commit messages 65 directly because we will be using git's autosquash feature in the next step, 66 which depends on the fixup! tag being present. 67 68 Do not merge in other branches, or rebase your review branches at this point. 69 Any changes that are made will show up in your reviews, and that will create 70 extra noise that your reviewers will have to ignore. If a reviewer requests 71 a change that requires your commit to be based off of a later version of 72 head, I would suggest deferring the change from the review and creating a 73 new review with the change once you hit step 5. 74 754. Once the reviews have been approved, you need to prepare your patch series 76 to be committed. This involves squashing the fixes made in code review 77 back into the original commit that they applied to. This gives you a clean 78 series of commits that are ready to be commited back to svn. 79 80 First, merge each of your review branches back into your main development 81 branch. For example: 82 83 $ git checkout myfeature_dev 84 $ for branch in review_D1234 review_D1235 review_D1236; do \ 85 git merge $branch || git mergetool -y || break; done 86 87 Next, do an interactive rebase to squash your code review fixes back into the 88 main commit: 89 90 $ git rebase -i -k review_D1234_base 91 92 review_D1234 should be the name of the *first* review that was created for 93 you in step 2. For every commit, your editor will be pulled up and you will 94 be given one last chance to edit your commit message. Make sure that you fill 95 in the "Reviewed by:" tag indicating who accepted the review. This would 96 be a good point to add other tags like MFC after:, Sponsored by:, etc. 97 98 The rebase will not introduce any actual changes to your code if done 99 properly. You can use this command to double-check that no changes were 100 inadvertently made here: 101 102 $ git diff myfeature_dev@{1} 103 1045. Finally, you should get up to date with the latest changes from head: 105 106 $ git pull --rebase origin master 107 108 It is not recommended that you combine this step with the rebase done in the 109 previous step. The reason for this is that if you perform an interactive 110 rebase that changes the commit that you branch from, it becomes much more 111 difficult to use the reflog to confirm that the interactive rebase did not 112 introduce unwanted changes. 113 114 At this point, you are ready to commit your changes to head. The importgit 115 script can be used to import your commits directly into git. 116 117II. importgit 118 119importgit is a script that can take a series of commits from git and commit them 120to a svn repository. The script uses the git commit messages for the svn commit 121message, which allows importgit to be fully automated. This does mean that once 122you start importgit, it will start commit things to svn without giving any 123further chance to sanity check what it's doing. 124 125importgit only supports importing commits that add or modify files. It does not 126support importing commits that rename or delete files, to ensure that git's 127rename detection heuristics do not introduce an error in the import process. 128importgit also does not support importing merge commits. Only linear history 129can be imported into svn. 130 131importgit must be run from a clean subversion checkout. You should ensure that 132the working tree is up-to-date with "svn up" before running importgit. 133importgit will run svn directly, so make sure that your ssh-agent is running 134and has your ssh key loaded already. Run importgit as follows: 135 136 $ importgit -r D1~..D2 -g /path/to/git/repo 137 138This will import every commit between D1 and D2, including both D1 and D2. The 139invocation is very similar to the invocation given to arcgit but there is an 140important point to note. When you rebased your commits as you followed steps 4 141and 5, the commit hashes of all of your commits changed, including C1 and C2. 142You must go back and find the new commit hashes of your commits to pass to 143importgit. Passing -r C1~..C2 would import your commits as they were *before* 144your code review fixes were applied. 145 146III. git-svn-rebase 147 148git-svn-rebase is a script that helps you keep current when using git 149plus subversion as outline in https://wiki.freebsd.org/GitWorkflow/GitSvn 150since it's otherwise a pain to have many branches active. It will rebase 151those branches that haven't been merged yet. Some tweaking may be needed 152if you have other, weird branches in your tree (including any stable 153branches). To run it just cd into the git subversion tree somewhere and 154type 155 $ git-svn-rebase 156and it will do its thing and leave the tree on the master branch. 157 158Your tree must be clean to start this, and while it tries to catch 159some failures, not all of them have been allowed for. 160 161IV. git-svn-init 162git-svn-init is a script that initializes the right git-svn connection as 163outlined in https://wiki.freebsd.org/GitWorkflow/GitSvn. It would be a precursor 164to the script git-svn-rebase. The script contains help, but generally you can 165run the script with no arguments and it will attempt to set up both src and 166ports repositories. 167