Helpful Git Commands

Michael O'Cleirigh edited this page Mar 26, 2011 · 8 revisions

Helpful Git Commands

This page contains useful git commands.

Get back the previous version of a file that has been deleted.

In Jan 2011 we deleted all of the hidden eclipse files from the repository and added them into the /.gitignore file.

So the idea is that those files can be generated automatically by the tool. However if local devs need to retrieve the original (last committed value version) this is the command to do it:


git show SHA-1:<full repository path>

The show command can show a specific file from a previous commit. And the standard labels of HEAD and HEAD^ ( for 1 commit before the current head) work:

git checkout core-1.4.x

cd jdk-1.5-parent/ddcalendar-parent/ddcalendar-examples

git show HEAD^:jdk-1.5-parent/ddcalendar-parent/ddcalendar-examples/.project > .project

Identify which files were deleted on each commit

The git log --diff-filter=D can be used to show the commits backward in time from the current HEAD where a file was deleted.

The --name-only option can be used to show the file names that were deleted for each commit

git log --format=oneline --diff-filter=D --name-only

8f3e43a68816772f3ba6b696ca768c063cdb94d0 push code cleanup
jdk-1.6-parent/push-parent-jdk-1.6/README

Here we can see that with commit 8f3e43a the file was deleted. There for it existed in the previous commit (8f3e43a^) and we can show the content like this:

git show 8f3e43a68816772f3ba6b696ca768c063cdb94d0^:jdk-1.6-parent/push-parent-jdk-1.6/README

A clone of wicketstuff-core/push-parent project.
The aim is to upgrade it to latest Cometd and Jetty versions.

Import a New project from an external git repository

These instructions are useful if you want to import an older wicketstuff project from the sandbox repository. But it could work for any external git repository.

** Approach: **

  • Add the external git repository as a remote
  • Fetch the remote branches
  • Create a local branch from the target remote branch.
  • Use git filter-branch --subdirectory-filter to extract a branch containing only the subdirectory of interest.
  • Import the entire filtered branch as one squashed commit against the wicketstuff branch.

In depth steps

In this case we are importing the wicketstuff-dojo project from the sandbox in the wicketstuff-dojo subdirectory into the jdk-1.5-parent/dojo-parent directory of the master branch.


$ git remote add sandbox git://github.com/wicketstuff/sandbox.git

$ git fetch sandbox

$ git checkout -b wicketstuff-dojo sandbox/master

$ git filter-branch --subdirectory-filter wicketstuff-dojo

$ ls

LICENSE.txt  pom.xml  wicketstuff-dojo-api  wicketstuff-dojo-resources

At this point we have a new branch called wicketstuff-dojo that contains the rewritten history for only that module.

But we have differnent naming conventions for the core project (i.e. we need to strip off the leading wicketstuff- parts of the project names and artifact names).


$ gvim pom.xml */pom.xml

[Edit the contents of the pom to change wicketstuff-dojo-api to dojo-api etc. ]

$ git commit -a -m "preparations for inclusion into wicketstuff-core"

Now we are ready to import the wicketstuff-dojo branch contents into the jdk-1.5-parent/dojo-parent directory of the master branch.

$ git merge -s ours --no-commit --squash wicketstuff-dojo
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested

$ git read-tree --prefix=jdk-1.5-parent/dojo-parent -u wicketstuff-dojo

$ ls jdk-1.5-parent/dojo-parent

LICENSE.txt  pom.xml  dojo-api  dojo-resources

$ git status
... confirm the correct/expected files are going to be added ...

$ git commit
[ modify the commit message to somthing suitably descriptive ]

At this point the module is in the master branch. You should make sure that the code still compiles and if so then either push the commits into the wicketstuff/core repository or issue a pull request from your repository.

Port Features from core-1.4.x into master (on top of an existing code)

As we get started with 1.5 releases much of the content in the master branch is from when the branch was originally split from the core-1.4.x branch.

Since most development has occurred on the core-1.4.x branch it is likely to be common that we want to merge the changes from the core-1.4.x branch back into master.

Approach:

  • Create a new project-1.4.x branch from core-1.4.x
  • Use git filter-branch --subdirectory-filter jdk-1.5-parent/module to create a new branch containing only the module files.
  • Switch back to master and use a subtree merge to merge the core-1.4.x module on top of the existing 1.5 module.
  • Commit everything as a squashed commit.

The only downside to this approach is that the filter-branch process creates new commits so if the end result is not squashed together it might not make sense.

In depth steps

$ git checkout core-1.4.x

$ git checkout -b jasperreports-parent-1.4.x core-1.4.x

$ git filter-branch --subdirectory-filter jdk-1.5-parent/jasperreports-parent

$ git ls-tree jasperreports-parent-1.4.x
100644 blob 54ca1ea045a5259f66be37ce28bf6d53a2ffd5fd    .cvsignore
100644 blob d9a10c0d8e868ebf8da0b3dc95bb0be634c34bfe    LICENSE.txt
040000 tree 43cedd6d3f165f4361e61f0451f7fd539e729d07    jasperreports-examples
040000 tree 42ecc877c2024ad25ff3025a811e456f3386d107    jasperreports
040000 tree 6ddeb41e46e8d1daa9e8516ed9ae030686be752e    licenses
100644 blob 05c303f26465dc24f0ffcf4bce1709ad9d9f8961    pom.xml
040000 tree a90503204708143e3e0914d9bbbb78ac18f44fbc    xdocs

$ git checkout master
  • From the root directory run the merge command git merge -s subtree --squash --no-commit jasperreports-parent-1.4.x.
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   jdk-1.5-parent/jasperreports-parent/.cvsignore
#       modified:   jdk-1.5-parent/jasperreports-parent/jasperreports-examples/pom.xml
#       modified:   jdk-1.5-parent/jasperreports-parent/jasperreports/pom.xml
#       modified:   jdk-1.5-parent/jasperreports-parent/jasperreports/src/main/java/org/
wicketstuff/jasperreports/EmbeddedJRReport.java
#       modified:   jdk-1.5-parent/jasperreports-parent/jasperreports/src/main/java/org/
wicketstuff/jasperreports/JRConcreteResource.java
#       modified:   jdk-1.5-parent/jasperreports-parent/jasperreports/src/main/java/org/
wicketstuff/jasperreports/JRImageResource.java
#       modified:   jdk-1.5-parent/jasperreports-parent/jasperreports/src/main/java/org/
wicketstuff/jasperreports/JRResource.java
#       modified:   jdk-1.5-parent/jasperreports-parent/pom.xml
  • Note that the pom's have changed back to 1.4-SNAPSHOT so you will have to change them back to 1.5-SNAPSHOT
  • After making the changes to the pom.xml's you can commit the merge git commit. Write a single commit message to represent the changes merged in from the core-1.4.x branch. Build up a description based on the squashed commits that make up the initial message.

Reverting a commit

If you committed something that is wrong to a public branch the only way to undo it is to create a new commit that undoes the damage.

Steps:

  • You get the SHA1 of the commit that was made in error.
  • You run git revert <SHA1> and then if there are conflicts resolve them with git mergetool.

This is also useful when cutting point releases because sometimes there will be a divergence in the upstream wicket version and the current stable version. For the point release we need to find (typically by a compile error showing up) the commits that changed things to the current upstream and revert them.

The wicketstuff-core-1.5-rc2.1 release tag has an example of this reversion process.