Introduction ------------ These instructions are wrote to contributors who tend to send lots of changes. The basics from howto-contribute.txt file are assumed to be read and understood by the time this file becomes useful. Setup ----- 1. Find a git server that can be reached from anywhere in internet anonymously. Github is for example a popular choice. 2. Create your own util-linux contributor repository, and push an upstream clone to there. 3. In these instructions the upstream remote repository is called 'origin' and the 'yourgit' is the contributor repo. cd ~/projects git clone git://git.kernel.org/pub/scm/utils/util-linux/util-linux.git cd util-linux git remote add yourgit git@github.com:yourlogin/util-linux.git git push yourgit Branches -------- 1. The name of your branch isn't crucial, but if you intend to contribute regularly, it's beneficial to establish a naming convention that works well for you. For instance, consider prefixing your branch name with the subsystem's name, such as blkid, libmount, etc. 2. Avoid using the 'master' branch for your contributions. The 'master' branch should be reserved for staying synchronized with the upstream repository. 3. Once you've completed your work, push your branch to your remote Git server. git checkout master git branch textual # spent here most of the effort git push yourgit textual:textual 5. Do not worry if you used stupid-and-wrong branch name, it can be fixed before submission. git branch -m stupid-and-wrong brilliant git push yourgit brilliant:brilliant :stupid-and-wrong Stay up to date --------------- 1. Ensure you have the latest from all remote repositories. 2. Merge upstream 'master' branch if needed to your local 'master'. 3. Rebase your working contribution branches. 4. Push the changes to 'yourgit'. git fetch --all git log --graph --decorate --pretty=oneline --abbrev-commit --all 5. If you notice upstream has changed while you were busy with your changes rebase on top of the master, but before that: 6. Push a backup of your branch 'textual' to 'yourgit', then git checkout master git merge origin/master git checkout textual git rebase master If rebase reports conflicts fix the conflicts. In case the rebase conflict is difficult to fix rebase --abort is good option, or recover from 'yourgit', either way there is some serious re-work ahead with the change set. 7. Assuming rebase went fine push the latest to 'yourgit'. git push yourgit master:master git push yourgit --force textual:textual The contributor branch tends to need --force every now and then, don't be afraid using it. 8. Push error with master branch If 'master' needs --force then something is really messed up. In that case it is probably the wise to abandon(*) local clone, and start all over from cloning upstream again. Once the upstream is cloned add again 'yourgit' remote and git push --mirror yourgit But be WARNED. The --mirror will nuke all of your stuff had in 'yourgit', that can cause data loss. (*)So don't remove the local clone, just move the directory to broken repos area. Sending pull request -------------------- 1. When you are happy with your changes sleep over night. This is not a speed competition, and for some reason looking the changes the next day often makes one to realize how things could be improved. The best this way you avoid changing the changes (that is always confusing). 2. Check the next day the changes compile without errors or warnings, and that regression tests run fine. make clean && make -j3 && make check Notice that regression tests will not cover all possible cases, so you most likely need to use the commands, features, and fixes you did manually. 3. If you need to change something. git rebase -i master # change something git push -f yourgit textual:textual 4. You have two ways how to send your pull request: 4.1 Github pull request (recommended) This is recommended way for your changes. All you need is to press "pull request" button on GitHub. 4.2. Send your work to the mailing list (optional) Assuming the changes look good send them to mail list. Yes, the all of them! Sending pull request with github is not visible for project contributors, and they will not have change to review your changes. Sending only the pull request, i.e., not each patch, to mail-list is also bad. Nothing is as good as seeing the changes as they are, and being able to find them from with your favourite web search engine from mail-list archive. Obviously the pull request content does not get indexed, and that is why it is worse. git format-patch --cover-letter master..textual git request-pull upstream/master https://github.com/yourlogin/util-linux.git textual > tempfile Take from the 'tempfile' the header: ---------------------------------------------------------------- The following changes since commit 17bf9c1c39b4f35163ec5c443b8bbd5857386ddd: ipcrm: fix usage (2015-01-06 11:55:21 +0100) are available in the git repository at: https://github.com/yourlogin/util-linux.git textual ---------------------------------------------------------------- and copy paste it to 0000-cover-letter.patch file somewhere near 'BLURB HERE'. Rest of the 'request-pull' output should be ignored. In same go fix the Subject: line to have reasonable description, for example Subject: [PATCH 00/15] pull: various textual improvements Feedback and resubmissions -------------------------- 1. Since you sent each patch to mail-list you can see which ones got to be responded. In case the feedback will result in changes to the submission then rebase, perform the changes, and push again to your remote. # you probably should use 'Stay up to date' instructions now git checkout textual git rebase master -i # edit something git add files git commit --amend # Add 'Reviewed-by:', 'Tested-by:', 'Signed-off-by:', 'Reference:', and # other lines near signoff when needed. Attributing the reviewers is a # virtue, try to do it. git rebase --continue git push -f yourgit textual:textual 2. Send a message to mail-list that the submitted change has changed, and that the new version can be found from https://github.com/yourlogin/util-linux/commit/0123456789abcdef0123456789abcdef01234567 3. There is no need to update the pull request cover letter. The project maintainer has done enough of this stuff to know what to do. Repository maintenance ---------------------- 1. When your remote branch is merged, or you got final reject, it is time to clean it up. git branch textual -d git push yourgit :textual 2. If you have other contributor repositories configured you may also want to clean up the branches the others are done with. for I in $(git remote); do echo "pruning: $I" git remote prune $I done 3. When all of your contributions are processed you should tidy up the git's guts. git reflog expire --all git gc --aggressive --prune=now Warning. That tidying is not good idea while you are actively working with the change set. You never know when you need to recover something from reflog, so keep that option available until you know the reflog is not needed. More branches, on top of branches, on top of ... ------------------------------------------------ Here is a one way of laying out multiple branches. git log --graph --decorate --pretty=oneline --abbrev-commit --all * 13bfff3 (HEAD, docs-update) docs: small improvements to howto-contribute.txt * 5435d28 (sami/more, more) more: do not call fileno() for std{in,out,err} streams * 3e1ac04 more: remove unnecessary braces * c19f31c more: check open(3) return value * 651ec1b more: move skipping forewards to a function from command() * bf0c2a7 more: move skipping backwards to a function from command() * 53a438d more: move editor execution to a function from command() * b11628b more: move runtime usage output away from command() * 6cab04e more: avoid long else segment in prbuf() * a2d9fbb more: remove 'register' keywords * c6b2d29 more: remove pointless functions * b41fe34 more: remove function like preprocessor defines * 1aaa1ce more: use paths.h to find bourne shell and vi editor * 016a019 more: return is statement, not a function * ff7019a more: remove dead code and useless comments * 1705c76 more: add struct more_control and remove global variables * 3ad4868 more: reorder includes, declarations, and global variables * 7220e9d more: remove function declarations - BRANCH STATUS: WORK IN PROGRESS * 04b9544 (sami/script) script: add noreturn function attributes * e7b8d50 script: use gettime_monotonic() to get timing file timestamps * 11289d2 script: use correct input type, move comment, and so on * 524e3e7 script: replace strftime() workaround with CFLAGS = -Wno-format-y2k * 0465e7f script: move do_io() content to small functions * 751edca script: add 'Script started' line always to capture file * f831657 script: remove io vs signal race * eefc1b7 script: merge doinput() and output() functions to do_io() * 9eba044 script: use poll() rather than select() * a6f04ef script: use signalfd() to catch signals * 4a86d9c script: add struct script_control and remove global variables * d1cf19c script: remove function prototypes * 6a7dce9 (sami/2015wk00) fsck.minix: fix segmentation fault * 5e3bcf7 lslocks: fix type warning * 3904423 maint: fix shadow declarations * 17bf9c1 (upstream/master, sami/master, kzgh/master, master) ipcrm: fix usage [...] The above gives a hint to maintainer what is the preferred merge order. The branches '2015wk00' and 'script' are ready to be merged, and they were sent to mail-list. The 'more' branch was not submitted at the time of writing this text. Mark-up the branch is not ready is clearly marked in the commit subject, that will need some rebaseing to before submission. Good order of the branches is; 1. First the minor & safe changes. 2. Then the ready but less certain stuff. 3. Followed by work-in-progress. If you go down this route you will get used to typing a lot of git rebase previous-branch git push -f yourgit branch:branch Alternatively rebase each branch on top of origin/master, which is not quite as good. How do you ensure your own changes are not in conflict with each other? And there is no hint of preferred merging order.