|
Git Repositories
I would suggest using something like SourceTree to work with git repositories (and if you are
managing a package use the built-in functionality in SourceTree to use gitflow for branches to
separate development and public releases).
This is a link to a pretty good tutorial and the
Git Pro book
See the following article about git and GitHub to think how to integrate git into your workflow:
Ten Simple Rules for Taking Advantage of
git and GitHub
The following are basically just list of useful commands beyond the basic that I've compiled in one
quick place. You should
look at tutorials to understand what these are doing.
Getting Started (Minimal you need to learn)
-
Make Local Git repository: note that if you are making a brand
new repository and plan to connect up to a central repository, it's better to
just clone it, rather than following these instructions. This is mainly for making a repository
from an existing directory.
Working on your local git repository
Once you have your repository set up locally, it will keep track locally of the differences in
each file, but only of those files you request to be tracked, and only when you request it. So
you need to 'add' files and 'commit' changes.
The above commands only add and commit your files to your local version control. To share it on
the central repository, you have to make a connection to the central repository and then sync
your changes to the central repository
Connect to existing central repository:
- Make New Local Git repository from existing Remote repository (via
SSH)
In the location you want the new repository to be created (i.e. 'cloned') type
git clone ssh://addressOfServerDirectory For example:
git clone ssh://isoform@beren.berkeley.edu/accounts/projects/isoform/gitRepos/projectName
- Connect Existing Local Git repository with Remote (see also this
online tutorial)
Inside the directory that has the git repository, type
git remote add origin ssh://addressOfServer For example
git remote add origin ssh://isoform@beren.berkeley.edu/accounts/projects/isoform/gitRepos/projectName
- To check what are your remote connections:
git remote -v
- To change the url of a remote:
git remote set-url origin ssh://addressOfServer
Syncing with the central repository on SCF Serve
git will not allow you to add anything that will conflict with what is on the repository (e.g.
changes uploaded to the repository by someone else). It forces you to incorporate those changes
locally before you inflict them on the rest of the world. Usually this is done automatically by
default merging, but sometimes if git can't resolve the differences between the two versions,
you have to manually go and fix the files.
So generally you need to first 'commit' your changes, 'pull' from the central repos., if needed
fix any differences and commit them (usually done automatically), then 'push' your new (merged)
version to the repository.
Useful for day-to-day
Setup a Central Git on SCF Server: We will usually use GitHub
for our respos, but occassionally we will want our repos on the SCF server.
It can frequently be useful to have a copy on the SCF account that you *can* work off of and run
scripts from, etc. You should do this by cloning a copy of the central repository to an
appropriate directory on the account (not under 'gitRepos'!). This local copy will need to push
and pull to the repository just like you would from your computer.
Merging/Fetching (see also documentation):
If you are combining your information with another via pull then git will first 'fetch' changes
from the central repos and them 'merge' together. git will try to resolve any conflicts (merge).
If there is a conflict it can't resolve, they you have to manually solve them before you can
push any changes (i.e. you can't add something that will break things for other people).
It can be better to do this separately if there are major changes between them. (post on why better)
git fetch
git merge origin/master
"origin/master" refers to the local copy of origin that you just fetched.
The main reason it can be safer, is that you can look and see what will happen and change options
(merge has different strategies for merging, including 'ours' and 'theirs' that defines where
the priority should be given). After you've gotten use to using git via pull, I would encourage
you to try this way and the techniques below and be careful before you use automatic merging. I
have 'lost' significant edits via merging -- of course I was able to recover them because they
were all on old commits!
- Resolving conflicts: Usually the best way to resolve conflicts
is to use
git mergetool
This should be done after git merge. This will launch a graphical tool to compare
and choose what you want to keep. (you may have to set what the graphical tool should
be; Mac has opendiff if you've installed XCode. On Windows you will probably need to
download a tool.)
-
By default, the results of merging are 'committed'. The program needs a merge message,
which can be given with the option -m so it doesn't open an edit screen.
- You can do a merge with out committing
git merge --no-commit origin/master
This allows you to look at the changes (e.g. with a difftool between HEAD and what's in
your local directory, see below). If you're okay with them, you can then commit them
like normal.
- If you did a merge that resulted in conflicts, you can undo the merge
(at least for committed files, see documentation) with
git merge --abort origin/master
- Advanced look at what a merge will do
If you do git fetch, you can then check out what would happen if you merge before
you merge. For example after a fetch,
- The following gives you a list of each file that would change:
git diff --name-status origin/master
- The following allows you to look, file-by-file, the differences between them
git difftool origin/master
You can also do difftool with just a single file,
git difftool origin/master path/to/file
difftool is just the gui version of diff command which gives you text that you
can also scroll through on your screen. See rholmes response to this
this question for a summary as to how different syntax is used by diff.
Reverting/Undoing
If you want to look at an old commit, you want the checkout command (see good tutorial here)
git checkout XXX
where XXX is the name of the commit. You should make sure that any of your changes you've made have
been committed or you will lose them. checkout brings then entire state of your commit at that time
into your directory (and makes your current commit go away).
To get back to where you were, you type,
git checkout master
checkout is good for looking at old commits and figuring out where what you want is (checkout is
also for moving between branches). But if you want to revert to an old commit or start making
changes based on an old commit, this isn't a good way to do it (if you accidently do this,
you're in a 'detached HEAD state' and see this help
page to see what you should do). The better way to get rid of changes and revert is git
revert or to work simultaneously on both create a new branch.
How do you find the name of a commit? You usually use the log command
git log
This spits out the information from each commit, including your comments. In the below commit the
name of the commit is the long string of numbers/letters
(682d89ca9e04d8c274d2d89419f9bb8a1b142c5a) though you don't usually have to type the whole thing
when you checkout (probably just enough of the beginning to uniquely identify it)
commit 682d89ca9e04d8c274d2d89419f9bb8a1b142c5a
Author: Elizabeth Purdom
Date: Fri Aug 7 17:10:55 2015 -0700
edits to main text
This is when you discover the utility (or not) of the comments you made at each change.
-
History of a single file:
git log -- filename
Log formats
log has a lot of options for how to format the output (see useful description here).
For example try the following commands:
git log --pretty=oneline
git log --stat
git log --author=epurdom -n=3
git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short
The last shows the graph of the commits across users.
- Undo changes since your last commit(see also this tutorial)
Frequently, you want to undo everything you've done and go back to your last commit. This
happens frequently if you use a synchronization program for your computer, and as a
result you've 'updated' everything in your git directory, but you don't want those
changes via a standard copy. You want to pull them in properly via a pull from the
repository. You also might realize that you didn't pull down the changes that are on the
repos, and rather than dealing with conflicts, you just want to trash anything you've
done. You can do
git checkout -- .
The '.' just means everything in the directory you're in (so do it at the top of the git
directory to do everything), but it can also be replaced with a specific filename.
You can also do
git reset --hard HEAD
to undo all uncommitted changes (note the difference, 'checkout' allows you to work on a
single file or folder using standard unix abbreviations for files; git reset does
everything. This is an indepth blog on reset).
Note checkout reverts only those files in the git repos. What about if you want to get
rid of files that haven't been committed yet? For example, you copied those files
manually from one computer to another (e.g. from SCF machine to yours via scp), and but
then they get added to git on the SCF machine. You won't be able to pull unless you
either a) add and commit your local versions of the file to the repository or b) delete
your local versions. Committing your version of the files in this setting will be a
headache (git doesn't nicely merge pdf files), but if you delete versioned files you
will delete them on the repository, so you can't just delete everything in the directory
(unless you are ready to reclone the repository)-- you need to get just those not
already on the repository.
git clean -f -d
Be very careful, because there's no undoing these (-f means force and -d means remove
directories too).
- Undo changes on committed files (see also this tutorial):
It's likely you want to get an old version of a single file to get something you lost,
etc. If you want to look at a specific file from an old commit,
git checkout XXX path/to/file
This is different from checking out an entire commit, because now you've pulled just the old
version of the file in the place of the current version of the file.
A simple thing to do would be to copy this old file to a new (unversioned) file name,
and then get your current version back via
git checkout master path/to/file
Then you can compare the two (e.g. using difftool) and make edits to the current version
from the old version.
If you truly want to revert to the old file (or entirely to an old commit) rather than
manually pulling in information from an old file, you probably want to use git revert.
See this
tutorial for the difference between checkout, revert, reset, and rebase in undoing
changes.
- Removing file from git without deleting local copy
git rm --cached myfile
Note that keeps your local copy intact, but other users, once they pull your
changes, will see their file get deleted (see stackoverflow
question)
Other useful tips
- Aliases: this tutorial describes how to do
this. It also has a collection of useful aliases
For example
git config --global alias.hist 'log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short'
creates a (global) git command on your machine (call with 'git hist') that makes a nicely
formatted output of the log history.
- To always commit .R, .m, .Rout files (always executed in top of the
directory, so gets everything , see the following link
For example, create a 'commitx' command:
git config alias.commitx '!git add *.Rout && git add *.m && git add *.R && git commit -a -m'
.gitignore files
Make good use of the .gitignore file so that your 'git status' command doesn't show a lot
of directories or files that you don't want. And also so you don't dump annoying files
onto the rest of the world when you do git add. There is a public repository of ignore files for
common scenarios.
Websites:
- http://mislav.uniqpath.com/2010/07/git-tips/
Back to top
Back to top
|