Git: CVS equivalent operations: Difference between revisions

From genomewiki
Jump to navigationJump to search
m (correction to step 12)
(Updated hgwdev links to .gi)
 
(17 intermediate revisions by 5 users not shown)
Line 1: Line 1:
1. check out a source tree: cvs co kent
==Check out a source tree: cvs co kent==


cd $HOME
cd $HOME
mv kent kent-cvs-old  # only if you have an existing cvs kent sandbox
mv kent kent-cvs-old  # only if you have an existing cvs kent sandbox
git clone yourlogin@hgwdev.cse.ucsc.edu:/data/git/kent.git/ kent
 
git clone yourlogin@hgwdev.gi.ucsc.edu:/data/git/kent.git/ kent
 
cd kent
cd kent




2. update a source tree: cvs up
==Update a source tree: cvs up==


git pull  # often this is all you need to do on your master branch
git pull  # often this is all you need to do on your master branch
Line 19: Line 22:




3. check in a changed file: cvs commit
==Check in a changed file: cvs commit==


git add changed-file
git add changed-file
Line 40: Line 43:


git push
git push
   (may need to do another git pull if someone else has pushed more  
   (may need to do another git pull if someone else has pushed more changes recently).
changes recently).


This is a fool-hardy alias:
This is a fool-hardy alias:
Line 53: Line 55:
pushing them into shared history.
pushing them into shared history.


4. review the history of a file: cvs log
==What are my outstanding commits==
 
git status
says:
Your branch is ahead of 'origin/master' by 3 commits.
but does not indicate what they are.  To get an idea of outstanding commits:
git log --author=YourName
to see all operations recently performed, then:
git diff origin/master
to see outstanding commits.
 
 
==Review the history of a file: cvs log==


git log
git log
git log somefile
git log somefile


Line 80: Line 95:
(See the genomewiki, search for git)
(See the genomewiki, search for git)


 
==Show who changed what: cvs ann==
5. show who changed what: cvs ann


git blame somefile
git blame somefile
Line 88: Line 102:




6. rename files (no cvs equivalent)
==Rename files (no cvs equivalent)==


git mv path newpath
  git mv path newpath
git commit -m 'renamed path to newpath for some good reason'
  git commit -m 'renamed path to newpath for some good reason'


You can add -C to git blame or git log to track renames.
You can add -C to git blame or git log to track renames.
Line 100: Line 114:
others.
others.


==Split or Join files (no cvs equivalent)==
Split example:
  cp file1.c file2.c
  vi file1.c  # remove one half
  vi file2.c  # remove the other half
  git add file1.c
  git add file2.c
  git commit -m 'split file1 into file1 and file2 for some good reason'
Join example:
  cat file2.c >> file1.c  # file1 will have the contents of old file1 and file2
  git rm file2.c
  git add file1.c
  git commit -m 'combined file2 and file1 into just file1 for some good reason'
IT IS VITAL TO HAVE ALL THE PARTS CHANGING
BE ADDED AND COMMITTED TOGETHER IN A SINGLE COMMIT.
If you fail to do this the file's history (git blame) will not be maintained.
You can add -C to git blame or git log to track renames and content movement.
There is a lot of new-found freedom to fix poorly chosen names
or do other larger re-arrangements of the directories and files
now, but before doing anything major you should check with
others.
If there's any chance you didn't get it right,
then don't push it.  If you need some time
to work out a complex rearrangment, or to test it,
you may wish to use a branch to develop in
a more controlled fashion.  Only merge and push
when it's right. Use git blame to check your
results are as expected.
==Extract any version of a file==
You can use the git show command to extract the
contents of any version of a file using any commit-Id or
tree-ish expression including branches and tags.
Having located the commit-Id or tree-ish using
git log, e.g.
git log src/hg/makeDb/doc/hg18.txt
you can fetch the desired file contents, e.g.


7. local branches and tags and merging and change branches
git show 13ca45a2eaac86644ff1411cc20b2a3bf25136bc^:src/hg/makeDb/doc/hg18.txt > hg18.old
 
Notice that this is the equivalent of old CVS:
 
  cvs up -p -r1.1234 hg18.txt > hg18.old
 
-p Send updates to standard output (avoids stickiness).
Notice this is the "little p" option, not -P which means prune.
 
==Local branches and tags and merging and change branches==


more on this in future
more on this in future




8. remotes and remote branches and tags and tracking branches:
==Remotes and remote branches and tags and tracking branches==
configuration and use with pushing and pulling.


more on this in future
configuration and use with pushing and pulling.  More on this in future.




9. Oops, I'm stuck with half-baked changes.
==Oops, I'm stuck with half-baked changes==
I want to just utterly lose all the uncommitted changes
I want to just utterly lose all the uncommitted changes
in my sandbox and return to my former self.
in my sandbox and return to my former self.
Line 120: Line 191:
This uses the HEAD by default.
This uses the HEAD by default.


Be careful because it resets ALL modified tracked files at every subdirectory level, i.e. the entire directory tree.
So if you do a trick like modifying ~/kent/src/inc/common.mk
to turn on extra debugging, and you don't check it in because you don't want to make it the default for everybody, then you would lose that tweak after a
reset --hard.


10. Oops, I just want to totally throw away all staged changes,
 
==Oops, I just want to totally throw away all staged changes==
but keep my working dir as it is.
but keep my working dir as it is.


Line 127: Line 203:




11. How to unstage just one file
==How to unstage just one file==


git rm --cached somefile
git reset HEAD somefile


This removes it from your stage
This removes it from your stage
but not from your working dir.
but not from your working dir.


If you have just added a brand new file,
ran git add and then decided you wanted
to keep the file, but unstage it, do this:


12. How to reset just one file
git rm --cached brandnewfile
 
 
==How to reset just one file==


git checkout HEAD somefile
git checkout HEAD somefile
Line 141: Line 223:
This will nuke any changes regarding somefile from the stage and also reset it in the working directory so it matches your HEAD commit.
This will nuke any changes regarding somefile from the stage and also reset it in the working directory so it matches your HEAD commit.


After a plain git reset to unstage everything, you can also recursively reset any edited files at your level and below with this:
You can also recursively reset any edited files at your level and below with this:
 
git checkout HEAD
 
 
Even when you can use git reset --hard without paths, be careful because it resets ALL modified tracked files at every subdirectory level, i.e. the entire directory tree.
So if you do a trick like modifying ~/kent/src/inc/common.mk
to turn on extra debugging, and you don't check it in because you don't want to make it the default for everybody, then you would lose that tweak after a reset --hard.


git reset --hard somefile
git checkout HEAD <b>.</b>  # dot refers to current directory


This will nuke any changes regarding somefile from the stage and also reset it in the working directory so it matches your HEAD commit.


 
==Diffing==
13. Diffing.


git diff has many flexible options.
git diff has many flexible options.
Line 162: Line 235:
a specific file or directory.
a specific file or directory.


git diff  # diffs working dir to stage
  git diff  # diffs working dir to stage
git diff --cached # diffs stage to HEAD commit.
  git diff --cached # diffs stage to HEAD commit
git diff A B  # A and B can be any branches, tags, commit-ids, tree-ish.
  git diff HEAD  #diffs working dir to HEAD
  git diff A B  # A and B can be any branches, tags, commit-ids, tree-ish.
 
 
[[Category:Git]]

Latest revision as of 00:18, 1 September 2018

Check out a source tree: cvs co kent

cd $HOME

mv kent kent-cvs-old # only if you have an existing cvs kent sandbox

git clone yourlogin@hgwdev.gi.ucsc.edu:/data/git/kent.git/ kent

cd kent


Update a source tree: cvs up

git pull # often this is all you need to do on your master branch

or

git fetch

fetch allows getting updates and comparing without merging. pull = fetch + merge.


Check in a changed file: cvs commit

git add changed-file git status git commit -m 'I fixed something important'

Note that git commit -a is very dangerous since it will grab any change anywhere in your entire directory tree and commit it. Do not use.

Instead, use this to add only tracked files at or below the current directory. This makes it behave like cvs commit which is relative to the current dir:

git add . -u # DO NOT FORGET THE -u or you will be sorry.

At least with this method you can still use git status to check what you have.

git push

 (may need to do another git pull if someone else has pushed more changes recently).

This is a fool-hardy alias:

 alias gcpp "git add \!*; git commit; git pull; git push"

!!! Committing and pushing are times of reflection. !!! This is your chance to catch problems before they escalate.

It is much better to group related changes together into a single commit with a well-written commit message. And test the changes before pushing them into shared history.

What are my outstanding commits

git status

says:

Your branch is ahead of 'origin/master' by 3 commits.

but does not indicate what they are. To get an idea of outstanding commits:

git log --author=YourName

to see all operations recently performed, then:

git diff origin/master

to see outstanding commits.


Review the history of a file: cvs log

git log

git log somefile

It lists the changes from newest to oldest.

There are tons of options with this command. It pipes it into more by default. You can pipe it into tig, or you can use -N where N is the number of lines to output before stopping.

There are also ways to filter the output by user. And you can specify a directory and get it and all subdirectories. And you could specify the time-frame. So you could say, show me everything that Hiram changed under kent/src/hg/lib in the last 3 weeks.

cd ~/kent; git log --stat --author=hiram --since="3 weeks ago" src/hg/lib

You can also specify changes in terms of tags and branch-tags, using tree-ish. (See the genomewiki, search for git)

Show who changed what: cvs ann

git blame somefile

git blame is reasonably fast and very powerful.


Rename files (no cvs equivalent)

 git mv path newpath
 git commit -m 'renamed path to newpath for some good reason'

You can add -C to git blame or git log to track renames.

There is a lot of new-found freedom to fix poorly chosen names or do other larger re-arrangements of the directories and files now, but before doing anything major you should check with others.

Split or Join files (no cvs equivalent)

Split example:

 cp file1.c file2.c
 vi file1.c  # remove one half
 vi file2.c  # remove the other half
 git add file1.c
 git add file2.c
 git commit -m 'split file1 into file1 and file2 for some good reason'

Join example:

 cat file2.c >> file1.c   # file1 will have the contents of old file1 and file2
 git rm file2.c
 git add file1.c
 git commit -m 'combined file2 and file1 into just file1 for some good reason'

IT IS VITAL TO HAVE ALL THE PARTS CHANGING BE ADDED AND COMMITTED TOGETHER IN A SINGLE COMMIT. If you fail to do this the file's history (git blame) will not be maintained.

You can add -C to git blame or git log to track renames and content movement.

There is a lot of new-found freedom to fix poorly chosen names or do other larger re-arrangements of the directories and files now, but before doing anything major you should check with others.

If there's any chance you didn't get it right, then don't push it. If you need some time to work out a complex rearrangment, or to test it, you may wish to use a branch to develop in a more controlled fashion. Only merge and push when it's right. Use git blame to check your results are as expected.


Extract any version of a file

You can use the git show command to extract the contents of any version of a file using any commit-Id or tree-ish expression including branches and tags.

Having located the commit-Id or tree-ish using git log, e.g.

git log src/hg/makeDb/doc/hg18.txt

you can fetch the desired file contents, e.g.

git show 13ca45a2eaac86644ff1411cc20b2a3bf25136bc^:src/hg/makeDb/doc/hg18.txt > hg18.old

Notice that this is the equivalent of old CVS:

 cvs up -p -r1.1234 hg18.txt > hg18.old

-p Send updates to standard output (avoids stickiness). Notice this is the "little p" option, not -P which means prune.

Local branches and tags and merging and change branches

more on this in future


Remotes and remote branches and tags and tracking branches

configuration and use with pushing and pulling. More on this in future.


Oops, I'm stuck with half-baked changes

I want to just utterly lose all the uncommitted changes in my sandbox and return to my former self.

git reset --hard

This uses the HEAD by default.

Be careful because it resets ALL modified tracked files at every subdirectory level, i.e. the entire directory tree. So if you do a trick like modifying ~/kent/src/inc/common.mk to turn on extra debugging, and you don't check it in because you don't want to make it the default for everybody, then you would lose that tweak after a reset --hard.


Oops, I just want to totally throw away all staged changes

but keep my working dir as it is.

git reset


How to unstage just one file

git reset HEAD somefile

This removes it from your stage but not from your working dir.

If you have just added a brand new file, ran git add and then decided you wanted to keep the file, but unstage it, do this:

git rm --cached brandnewfile


How to reset just one file

git checkout HEAD somefile

This will nuke any changes regarding somefile from the stage and also reset it in the working directory so it matches your HEAD commit.

You can also recursively reset any edited files at your level and below with this:

git checkout HEAD . # dot refers to current directory


Diffing

git diff has many flexible options. You can use branch-tags, tags, tree-ish. You can specify entire commit states, you can limit it to a specific file or directory.

 git diff  # diffs working dir to stage
 git diff --cached # diffs stage to HEAD commit
 git diff HEAD   #diffs working dir to HEAD
 git diff A B   # A and B can be any branches, tags, commit-ids, tree-ish.