Showing posts with label GIT Commit history. Show all posts
Showing posts with label GIT Commit history. Show all posts

Thursday, 27 December 2018

GIT: Rewriting commit history with git filter-branch

48.1. Using the git filter branch command (filter-branch)

The git filter-branch command allows you to rewrite the Git commit history. This can be done for selected branches and you can apply custom filters on each revision. This creates different hashes for all modified commits. This implies that you get new IDs for all commits based on any rewritten commit.
The command allows you to filter for several values, e.g., the author, the message, etc. 
Using the filter-branch command is dangerous as it changes the Git repository.
 It changes the commit IDs and reacting on such a change requires explicit action 
from the developer, e.g., trying to rebase the stale local branch onto the 
corresponding rewritten remote-tracking branch.
For example, you can use git filter-branch if you want to remove a file which contains a password from the Git history. Or you want to remove huge binary files from the history. To completely remove such files, you need to run the filter-branch command on all branches.

48.2. filter-branch examples

The following command extracts a directory from a Git repository and retains all commits for this subfolder.
git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME  BRANCH-NAME
The following command replaces the email address of one author from all commits.
git filter-branch -f \
--env-filter 'if [ "$GIT_AUTHOR_NAME" = "Lars Vogel" ]; then \
GIT_AUTHOR_EMAIL="lars.vogel@gmail.com"; fi' HEAD)

GIT: Commit history of a repository or certain files

Gitk can be used to visualize the history of a repository of certain files.
In some cases simply using git blame is not sufficient in order to see all details of certain changes. You can navigate to the file location in the target git repository and use the gitk [filename] command to see all commits of a file in a clear UI.
In this screenshot we can see all commits of the ShowViewHandler.java by using the gitk ShowViewHandler.javacommand:
gitk command for the ShowViewHandler
On Linux you can easily install gitk by using the sudo apt-get install gitk command in a terminal.

GIT: Analyzing the commit history with git log

17.1. Using git log

The git log command shows the history of the Git repository. If no commit reference is specified it starts from the commit referred to by the HEAD pointer.
git log

git log HEAD~10 

git log COMMIT_REF 
shows the history of commits starting from the HEAD~10 commit
shows the history of commits starting from the COMMIT_REF commit

17.2. Helpful parameters for git log

The following gives an overview of useful parameters for the git log command.
git log --oneline  
git log --abbrev-commit 
git log --graph --oneline 
git log --decorate 
--oneline - fits the output of the git log command in one line. --online is a shorthand for "--pretty=oneline --abbrev-commit"
--abbrev-commit - the log command uses shorter versions of the SHA-1 identifier for a commit object but keeps the SHA-1 unique. This parameter uses 7 characters by default, but you can specify other numbers, e.g., --abbrev-commit --abbrev=4.
graph - draws a text-based graphical representation of the branches and the merge history of the Git repository.
decorate - adds symbolic pointers to the log output
17.3. View the change history of a file
To see changes in a file you can use the -p option in the git log command.
git log -- [file_reference] 

git log -p -- [file_reference]  

git log --follow -p -- [file_reference] 
- shows the list of commits for this file
- the -p parameter triggers that the diffs of each commit is shown
--follow allow include renames in the log output

17.4. Configuring output format

You can use the --pretty parameter to configure the output.
# command must be issued in one line, do not enter the line break
git log --pretty=format:'%Cred%h%Creset %d%Creset %s %Cgreen(%cr)
 %C(bold blue)<%an>%Creset' --abbrev-commit
This command creates the output.
Git log pretty output
17.5. Filtering based on the commit message via regular expressions
You can filter the output of the git log command to commits whose commit message, or reflog entry, respectively, matches the specified regular expression pattern with the --grep=<pattern> and --grep-reflog=<pattern> option.
For example the following command instructs the log command to list all commits which contain the word "workspace" in their commit message.
git log --oneline --grep="workspace" 
Greps in commit message for "workspace", oneline parameter included for better readability of the output
There is also the --invert-grep=<pattern> option. When this option is used, git log lists the commits that don’t match the specified pattern.

17.6. Filtering the log output based on author or committer

You can use the --author=<pattern> or --committer=<pattern> to filter the log output by author or committer. You do not need to use the full name, if a substring matches, the commit is included in the log output.
The following command lists all commits with an author name containing the word "Vogel".
git log --author="Vogel"