-
Notifications
You must be signed in to change notification settings - Fork 61
Git FAQ
This page is broken down by use cases. Look for the heading that describes what you are trying to do, and follow the instructions.
Github's own instructions for setting up git are here: https://help.github.com/articles/set-up-git
Especially if you don't have a new enough git to have "credential helper", you may want to set up an SSH keypair (and maybe let ssh-agent save you from retyping the password) https://help.github.com/articles/generating-ssh-keys
Note that only SSH clone urls are subject to SSH keys.
- Go to: https://github.com/kframework/k
- Click the "Fork" button in the upper right, then select your personal account.
- In your git console, run
git clone
with the argument in the right sidebar on github. For example, Dwight runsgit clone https://github.com/dwightguth/k.git
. If you normally connect to git via SSH (e.g. because you want to specify an SSH key), you would use the SSH clone URL:git clone [email protected]:dwightguth/k.git
.
In order to simplify the process of manipulating changes, it is often very convenient to have a local branch named "master" which tracks "origin" and contains no local changes. This allows you to easily create new clean branches by running the command git checkout -b <branch_name> master
. These branches then contain your changes so that the "master" branch remains unmodified and in sync with the main kframework repository.
To create a new feature branch to commit your changes to, run the above command. However, if you already have made changes to your local "master" branch, it is advisable to move these changes onto a feature branch. To do this:
git checkout -b <branch_name> master # this creates a branch containing your changes so they are not lost when you rebase master
git checkout master # move back to master branch so that the following command works correctly
git reset --hard upstream/master # reset working copy and all local commits to the upstream/master which is clean
By making your changes only on branches of your local "master" branch, you simplify the process of merging, rebasing, moving changes between branches, etc.
Sometimes you want to branch off a branch other than master, for example when you are working on a long-running feature branch and want to submit code reviews, or when you are working on a change that depends on another change which has not yet been merged into master. To do this, you have two options.
- Run
git checkout -b <branch_name>
from the branch you wish to branch off of. - Run
git checkout -b <branch_name> <branch_to_branch_from>
. The first of these is equivalent to the second with the caveat that <branch_to_branch_from> becomes the current branch. For more information, seegit help checkout
.
By default, when you run "git push", you might see the following message:
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:
git config --global push.default matching
To squelch this message and adopt the new behavior now, use:
git config --global push.default simple
Personally I recommend using simple to avoid accidentally pushing to branches you don't want to push to, but it's up to you. Just make sure you never push changes to the master
or nightly
branches of the main K framework repository (i.e. upstream). The easiest way to ensure this is to never commit changes to these branches. See the previous section for more details.
- Log into github and click "Pull request" next to the line that says "This branch is commits ahead and commits behind master".
- If you are pulling into a branch other than master, make sure you click "Edit" at the top and then select that branch where it says "Base".
- Make sure you are submitting the correct change, type up a description for it, then submit it. This automatically emails everyone watching the K framework repository except yourself.
- If you need a particular user to review your change, you should tag their Github user ID in the pull request description. For example to ask me to review something you might say "@dwightguth Please review."
- At this point it becomes the responsibility of reviewers to comment on your change and either approve it or request modifications. They can do this by accessing the pull request online and commenting on the change or on specific lines of code. If they request changes, you can update the pull request simply by pushing further changes on the same branch to your fork. Once the pull request is approved, you are free to click the "Merge pull request" button on the bottom of the pull request screen to automatically merge and close the pull request.
- Note that any push made to the same branch after the pull request is opened but before it is closed will add that commit to the pull request. To continue working on a different change during that time period, you must work on a branch.
- Create a short-term feature branch in your fork by running the command
git branch <branch_name> <commit_id_to_branch_from>
. For example to create a branch named "foo" from the commit immediately prior to the most recent, you might rungit branch foo HEAD^
. For information on how to specify commits, seegit help revisions
- Switch to the new branch by running
git checkout <branch_name>
. - Start making your new change. When it comes time to perform a pull request, push the changes upstream to the branch you created by running
git push origin <branch_name>
. - Proceed from section "Create the pull request"
- (do this once) run
git remote add upstream [email protected]:kframework/k.git
(or use HTTPS if you prefer). This adds a remote repository to your local repository for the kframework/k repository. - Run
git pull --rebase upstream <branch_name>
to sync a particular branch of your local repository with the main repository. Do this if your branch is behind the master repository. DO NOT DO THIS IF YOUR CODE HAS ALREADY BEEN CODE REVIEWED. This will destroy the commit history that the reviewer saw when they reviewed, and make it harder to continue the review later. In this case, rungit pull upstream <branch_name>
in order to merge instead. - Run
git push origin <branch_name>
to sync your fork with your local repository, which should now contain the latest changes. If you get a message saying something similar to:! [rejected] master -> master (non-fast-forward)
You should try to determine whether or not your fork contains changes that your local repository does not which you want to keep. If it does, you will need to incorporate those changes into your working copy in order to proceed. However, if you are okay with removing the history from your fork which differs from the local repository, you can rungit push origin <branch_name> -f
to override this error.
- Run
git fetch upstream
to ensure that you have downloaded the latest version of the remote branch to your local repository. - Run
git checkout <branch_name>
to check out the branch. Pay attention to whether it says it is tracking upstream or origin. - If it says it is tracking origin, you may be out of date against the main repository, so you should run
git pull --rebase upstream/<branch_name>
. - If it says it is tracking upstream, this is the first time you have checked out this branch, and you need to push it to your fork. Run
git push -u origin <branch_name>
.
- Ensure that you have added that person's remote to your repository by running
git remote -v
and checking for a remote named after their github username. If it is not present, you can add it withgit remote add <username> [email protected]:<username>/k.git
- continue from the above instructions, except substitute their usename everywhere it says
upstream
.
See http://git-scm.com/book/en/Git-Branching-Rebasing for more information on when not to rebase. In summary, don't rebase anything after it has been made publicly available, either by being merged into the main K framework repository, or by being code reviewed by someone else. Before that point, feel free to rebase your changes however you like in order to make your history more to your liking.
git status
will tell you what branch you are on, and summarize changes you've made, divided into the changes you've staged (marked to include in your next commit), and other changes. It also includes useful reminders of the commands to unstage or to completely forget and overwrite the local changes.
With the --ignored
flag it also lists all files that exist but are covered by the .gitignore
files, in case you want to check on that.
gitk
displays a graph of the commit and branch history starting from whatever you've checked out, annotating any of the older commits that happen to be the head of some branch or tagged with some tag,
and letting you inspect lots of things.
It can take as arguments as many local branch names like and remote branch names like origin/ as you like, and then will show a combined graph including history back from each of those points. (there are tons of extra options and argument forms you can find in man pages, one particularly useful form is <branch>...<branch>
to show only commits from the two branches back up to common ancestors, if you are thinking about a merge).
The command git checkout -- <file>
will overwrite file with it's contents in whatever version you have checked out, replacing deleted files and overwriting modifications.
The easiest way to use it is probably to run git status
whose output includes a reminder of this command and a list of all (non-ignored) modified and deleted files so you can just copy and paste filename.
"svn up" was used to replace deleted files, "git pull" doesn't do that because it considers deleting files to be possibly an intentional local change that it doesn't want to overwrite.
Sometimes you try to rebase changes in order to sync your branch with the upstream repository and run into weird problems where it has conflicts that you don't think should be there, or it adds a bunch of changes that aren't yours to your pull request.
In my experience this is generally because your commit history is not what you expect. Perhaps you have commits in your history in two different places, or you are branched from a different commit than you thought. To resolve this issue, we can use cherry-picking.
- From a clean master branch, create a new branch for your change to be transplanted into. To do this, run
git checkout -b <branch_name>
. If you do not have a clean master branch, see the section "Creating a new clean branch to contain your change". - From your clean new branch, cherry-pick the changes you want. If you have only one change, you can do this by running
git cherry-pick <branch_name>
. Otherwise, collect the hashes of all the commits you want to cherry pick and rungit cherry-pick <hash1> <hash2> ...
.