Git rev-list
Overview
In this article, we will learn about Git Rev List. So, before getting started with the topic, let us get a short overview of the topic.
Git Rev List: git rev-list is a very useful command, which we use to fetch the list of commit objects in reverse sequential order. The Git rev-list basically, lists the commits that can be reached by following the provided parent links mentioned in the commit(s), but does not include the commits that can be reached from the commit(s) that are provided with a ^ in front of them.
Pre-requisites
Before getting started with the topic, you must have a clear understanding of a few topics like :
Introduction to Git Rev List
git rev-list is a very useful command, which we use to fetch the list of commit objects in reverse sequential order. The Git rev-list basically, lists the commits that can be reached by following the provided parent links mentioned in the commit(s), but does not include the commits that can be reached from the commit(s) that are provided with a ^ in front of them. By default, the result is presented in reverse sequential order.
This git rev-list command can be compared to a set operation. commits that can be reached by following the provided parent links mentioned in the commit(s) create a set and then commits that can be reached from the commit(s) that are provided with a ^ in front of them get removed from the set. The output of the command shows the remaining commits. To further restrict the outcome, various options and path parameters can be used.
Hence, the following command of Git Rev List:
Explanation :
The above command will return the list, which will consist of commits that are approachable from the hello and world, however it will exclude the commits that are approachable from def, as a ^ is provided in front of it.
We can also use the <commit1>..<commit2> notation, in place of <commit1> ^<commit2>. For instance, both of the following are acceptable :
<commit1>…<commit2> is another unique notation that is helpful for merging. The neutral difference between the two operands is the outcome list of commits. The two commands listed below are equivalent :
From the above definition, you might have got a clear understanding that git rev-list is really a very important command, due to its ability to create and navigate commit ancestry graphs. Let us now look at the synopsis of this git rev-list command.
Synopsis
Explanation : The above-given code is the synopsis of the Git rev list command. The format of this synopsis is git rev-list [<options>] <commit>… [[--] <path>…] where all the commands inside the square bracket [] are different options of git rev-list command, using which we can perform different tasks.
OPTIONS
Git rev list is really a very important command, due to its ability to create and navigate commit ancestry graphs. Due to this it consists of a wide range of options that allow it to be utilized by commands as different as git repack and git bisect.
Commit Limiting
Additional commit limits may be used in addition to providing a range of commits that should be reported using the specific notations described in the description.
Unless otherwise stated, adding extra arguments often further restricts the output (for example, --since=<date1> restricts to commits made after <date1>, and using it with --grep=<pattern> further restricts to commits whose log message contains a line that matches <pattern>).
Please note that these types of options are used before formatting and commit ordering options, for example --reverse
Explanation :
By using these types of options we can limit the number of commits to output.
Explanation :
Before displaying the commit output, skip a certain number of commits.
Explanation :
Show commits made after a certain date only.
Explanation :
Show all commits that occurred after a certain date. Instead of stopping at the first commit that is greater than a certain date, this visits every commit in the given range.
Explanation :
Display commits made before a certain date.
Explanation :
Limit the output of the commits to the given time frame.
Explanation :
Returns the commits, shortlisted on the basis of committer/author which matches with the given pattern (regex). In case there are multiple --author=<pattern>, commits having an author that matches with the specified patterns are returned (same thing in case of more than one --committer=<pattern>).
Explanation :
Returns the commits, shortlisted on the basis of reflog entries that match with the given pattern (regex). In case there are multiple --grep-reflog, commits having a reflog message that matches the specified patterns are returned. Use of this option without --walk-reflogs will throw an error.
Explanation :
Returns the commits, shortlisted on the basis of a log message which matches with the given pattern (regex). In case there are multiple --grep=<pattern>, commits having a message that matches the specified patterns are returned.
Explanation :
Limit the output of commits to those that match with all of the supplied —grep, and restrict those commits that at least match with one of the supplied —grep.
Explanation :
Only include commits with log messages that don't match the given pattern identified with the --grep=<pattern> in the commits output.
Explanation :
Ignoring the letter case, the limiting patterns of the regEx are matched.
Explanation :
This is a default option, which limits the patterns on the basis of basic regular expressions.
Explanation :
Instead of the basic regEx which is the default, the limiting patterns are considered extended regEx.
Explanation :
The limiting patterns are considered as fixed strings (don't consider a pattern to be a regex).
Explanation :
The limiting patterns are considered as Perl-compatible regex.
Capability for these regular expressions is a compile-time requirement that is optional. Git will crash if you use this option if it wasn't built with the capability for them.
Explanation :
when a certain path leaves the tree, it pauses.
Explanation :
Only the merge commits are printed. This option and the --min-parents=2 option are exactly similar.
Explanation :
Commits that have multiple parents are not printed. This option and --max-parents=1 is exactly similar.
Explanation:
Commits that have at most (or at least) that much of parent commits are only shown. Generally, --max-parents=1 is similar to --no-merges, and --min-parents=2 is similar to --merges. Now, --max-parents=0 provides all root commits, and --min-parents=3 all octopus format merges.
Limits are reset to zero (no limit) by using the --no-max-parents and --no-min-parents. Similarly, --max-parents=-1 (No upper limit is denoted by negative numbers) and --min-parents=0 (commits with 0 or more than 0 parents)
Explanation :
After noticing a merging commit, it just follows the initial parent commit when looking for commits to add. We can use this option to get a better outline, when we want to see the growth of a specific topic branch as topic branch merges often just involve adapting to the latest upstream from period to period, You can choose this option to disregard any particular commits that the merging added to our history.
Explanation :
After noticing a merging commit, it just follows the initial parent commit when looking for commits to exclude (with a ^). Since the topic branch is split from the remote branch, this option may be used to identify the series of modifications made to the topic branch, considering that arbitrary merges might be legitimate topic branch modifications.
Explanation :
The ^ prefix (or lack thereof) meaning is reversed for all subsequent revision specifiers up to the next --not.
Explanation :
Assume that HEAD and all of the references in the refs/ directory are provided within the command line as <commit>.
Explanation :
Assume that all of the references in the refs/head directory are provided on the command line as <commit>. If <pattern> is provided, branches are limited to ones that match the provided shell glob. If the pattern doesn't have a ?, *, or [ in the ending, /* is assumed.
Explanation :
Assume that all of the references in the refs/tags directory are provided on the command line as <commit>. If <pattern> is provided, tags are limited to ones that match the provided shell glob. If the pattern doesn't have a ?, *, or [ in the ending, /* is assumed.
Explanation :
Assume that all of the references in the refs/remotes directory are provided within the command line as <commit>. If <pattern> is provided, remote-tracking branches are limited to ones that match the provided shell glob. If the pattern doesn't have a ?, *, or [ in the ending, /* is assumed.
Explanation :
Assume that all of the references matching with shell glob <glob-pattern> are provided within the command line as <commit>. If leading refs/ are missing, it is automatically added. If the pattern doesn't have a ?, *, or [ in the ending, /* is assumed.
Explanation :
It doesn't include references that match with the <glob-pattern> which would be considered by other options like --all, --branches, --tags, --remotes, --glob. Exclusion patterns from repeating this option build up until the --all, --branches, --tags, --remotes, and --glob options (accumulated patterns are not cleared with other arguments or options).
We should never begin the pattern with refs/heads, refs/tags, or refs/remotes while applying to the --branches, --tags, or --remotes, respectively, however, when used with --glob or --all, they must start with refs/. If the pattern doesn't have a ?, *, or [ at the end, /* is assumed.
Explanation :
Assume that all of the objects that are referred to by reflogs are provided within the command line as <commit>.
Explanation :
Assume that all of the objects that are referred to by ref tips of alternative repositories are provided on the command line. Any repository whose object directory is listed in objects/info/alternates is considered an alternate repository. Core.alternateRefsCommand, etc., can change the list of included objects. Check out git-config for clear understanding.
Explanation :
This option will analyze all the working trees by default when there are several working trees (see git-worktree): --all, --reflog and --indexed-objects. They are forced by this option to analyze only the current working tree.
Explanation :
This option ignores the incorrect object name if given in the input.
Explanation :
This option read the <commit> from the given input, along with the <commit> specified within the command line. If there is a --separator mentioned, it will halt the reading of commits, and begin reading the paths for limiting the resulting output.
Explanation :
There is nothing returned as output by this option. The primary use of this option is to permit the user to analyze the exit status code and to check if the object range is completely connected or not. As the output is not required to be formatted, it is quicker than forwarding stdout to the path /dev/null.
Explanation :
Suppress regular output and report the total amount of bytes for the usage of on-disk storage occupied by the specified objects or commits. This option is similar to piping the result into the given git cat-file --batch-check='%(objectsize:disk)', the only difference is it executes more quickly (especially when using --use-bitmap-index). Look at the CAVEATS part in git-cat-file, for understanding the on-disk storage in depth. The on-disk storage capacity is shown as a human-readable string with the optional value human (e.g. 12.24 Kib, 3.50 Mib).
Explanation :
This option is similar to --cherry-pick, the only difference is instead of omitting the equivalent commits, it marks them with = sign, and inequivalent commits are marked with + sign.
Explanation :
When the collection of commits is constrained by symmetric difference, ignore those commit that makes a similar change as some other commit on another side.
For instance, let's suppose there are 2 branches, C and D, one of the traditional ways is to use the --left-right, to enlist all the commits on just a single side of the branches (see the instance in the --left-right option's description given below). However, it displays those commits that were selected arbitrarily from the different branches (for instance, "3rd on D" may be arbitrarily selected from branch C). Such commit pairs are not included in the output when using this option.
Explanation :
Only those commits which are marked as < resp. > by the --left-right is only listed with the help of this option. Basically, relevant commits with a symmetric difference are only listed with this option.
For instance, the option —cherry-pick —right-only C...D will exclude any contributions from D that are either in C or are patch-equivalent to a commit in C. Basically, all the + commits from git cherry C D are listed by this option. In more detail, the exact list is provided by the --cherry-pick --right-only --no-merges command.
Explanation :
This option is similar to --right-only --cherry-mark --no-merges;, and it is used to restrict the result to the commits on our end and check those commits that are applied to the opposite end of the forked history using the git log --cherry upstream...myBranch, which is equivalent to git cherry upstream myBranch.
Explanation :
Using this option, rather than going through the ancestry chain of commits, We may browse through the reflog records from the oldest ones to the recent ones. If you are using this option you cannot exclude any commits, that is you cannot use the ^commit1, commit3..commit4, and commit3...commit4 notations.
This results in the output having two additional lines of data pulled from the reflog when —the pretty format is set to something other than reference and online (for known reasons). In the output the reflog designator is represented as ref@{timestamp} (where the entry consists of timestamp) or as ref@{Nth} (Where the reverse-chronological index is Nth in the reflog), on the basis of a few rules :
- It displays the index format if the initial point is stated as ref@{Nth}.
- It displays the timestamp format if the initial point is stated as ref@{now}.
- If neither of the formats is used, however --date is mentioned on the command line, it will display the timestamp in the desired --date format.
- Otherwise, the index format will be displayed.
when the option --pretty=oneline is used, the information precedes the commit message on a similar line. We cannot combine this option with --the reverse. Refer also git-reflog for clear understanding.
Under --pretty=reference, it will hide the information.
Explanation :
Show references to conflicting files that do not exist on every head to merge after an unsuccessful merging.
Explanation :
Boundary commits are excluded and not shown in the output. It uses the - as a prefix for boundary commits.
Explanation :
Applying the pack bitmap index (if one is available), accelerates the traversal. Note that tree and blobs won't have their corresponding paths reported when traversing with --objects.
Explanation :
As objects are examined, print progress reports to stderr. With each and every progress update, it will print the <header> text.
History Simplification
Sometimes only the history parts interest you, for instance, a particular <path> is modified by the commits. But the History Simplification consists of two parts, one is committed selections, and the other part is how to select the commits, as there are different methods to simplify the history.
The commits are selected on the basis of the following options as shown :
Explanation :
Commits that alter the listed "paths" are chosen.
Explanation :
The commits that a branch or tag refers to are chosen.
Note to give a meaningful history, extra commits can be displayed.
The options given below can impact the way the simplification is carried out :
Default mode
Explaining the last state of the tree, it simplifies the history to the basic history. It basically merges the branches with the same content, hence making history simplest.
Explanation :
All the default mode commits are included, but it also includes the merge commits that are TREESAME to a later parent, but not TREESAME to the first parent. With the help of this mode, we can see the merge commits that "first introduced" altering the branch.
Explanation :
It is similar to the default mode, but some history is not pruned.
Explanation :
Only the chosen commits are displayed, along with several that have a significant history.
Explanation :
Every commit in the condensed history is displayed.
Explanation :
As there are no chosen commits contributing to this merge, an additional option to --full-history can be used to eliminate certain unnecessary merges from the resultant history.
Explanation :
When provided a range of commits to show (for example, commit1..commit2 or commit2 ^commit1), this option only shows those commits which are descendants of <commit>, ancestors of <commit>, or the original <commit>. Use commit1 (the excluded portion of the range) as the <commit> if no commit is supplied. If a commit is an ancestor or descendant of one of them it is included.
Explanation :
Commits that are not TREESAME to any parent are included.
Explanation :
Includes all commits that are walked.
It should be noted that even without —full-history, this simplifies merges since, if any one of the parents is TREESAME, we merely follow that one and never walk the other side of the merge.
Bisection Helpers
Let us discuss the bisection helpers type option
Explanation :
Specify only the single commit object that is about midway between the including and excluding commits. Please make sure, that the references that are bad bisection refs/bisect/bad are added to the including commits (in case if they exist), and the references that are good bisection refs/bisect/good-* are included to the excluding commits (in case if they exist). So let's suppose no references in refs/bisect/ are there if the output is midpoint,
the 2 commands' output would be
Explanation :
would be almost equal in length. This reduces finding the modification that causes a regression to a binary search: constantly create and check the latest "midpoints" unless the length of the commit chain is 1.
Explanation :
The calculations are identical to those of —bisect, with the exception that this produces text that is ready for the shell to evaluate. The midpoint revision name will be assigned as the variable bisect_rev by these lines, and the total expected commits are checked after the bisect_rev is checked with bisect_nr, the total expected commits are checked if bisect_rev proves to be good to bisect_good, the total expected commits to be checked if bisect_rev proves to be not good to bisect_bad, also the total commits that are been bisected by us to bisect_all.
Explanation :
This generates a list of every commit object between the excluded and included commits, sorted by the distance between them. References in refs/bisect/ remain unused. The one furthest away from them is shown first. (By --bisect, just this one is displayed).
This is advantageous since it makes picking a better commit to check simple when you wish to avoid testing a few of the commits for a particular reason (for instance, the commits that are not compiled).
We can use this option with the --bisect-vars, if we are using it, in this scenario, once all the commit objects have been sorted, a similar text will be visible as if only --bisect-vars is used.
Commit Ordering
Commits are returned in reverse sequential order by default.
Explanation :
This option shows all the children before showing their parents, or else commits are displayed in the timestamp order.
Explanation :
This option shows all the children before showing their parents, or else it displays the commits in the author's timestamp order.
Explanation :
This option shows all the children before showing their parents, and it avoids displaying commits on more than one line of history intermixed.
For instance, in a commit history like this:
In the above commit history, the numbers are denoted by the commit timestamps order, --date-order, and git rev-list displays the timestamp of commits in order: 8 7 6 5 4 3 2 1.
By using t--topo-order, the timestamp of commits will be displayed in order 8 6 5 3 7 4 2 1 (or 8 7 4 2 6 5 3 1); you can observe before displaying the newer commits, some older ones are displayed first, to keep the commits from two simultaneous development tracks from being shown together.
Return the commits in the reverse order that are selected to be displayed. We cannot combine this option with --walk-reflogs.
There are other options types like the Object Traversal option, and Commit Formatting options. If you want to read about them in detail you can refer to Git-rev-list-options.
Example
Let us now look at the example of the Git rev list in points for a clearer understanding.
- For printing the list of commits that is accessible from the current branch.
- For printing the list of commits that is present on this branch, but not in the upstream branch.
- For formatting the commits by including their author and the commit message (check out the porcelain git-log).
- For formatting the commits and their differences (check out the porcelain git-log, which can accomplish this in one step).
- For printing the list of commits that have recently impacted any file in the directory of Documentation on the current branch.
- For printing the list of commits that is made by you in the last 12 months (one year) on any branch, tag, or other references.
- For printing the list of objects that can be accessed from the current branch, that is, all the blobs, trees, and commits they contain.
- Compare the disc size of all objects that can be reached, verses that can be reached through reflogs, versus the overall packed size. You may use this to determine whether using git repack -ad will result in a smaller repository size. (by removing objects that are unreachable), and whether expiring reflogs may be beneficial.
- Give the disc space consumed by each branch, excluding any items currently being used by the current branch. This can identify outliers that are increasing the size of the repository (For instance, if somebody mistakenly committed large build artifacts).
- In a single group of refs, the on-disk sizes of branches are compared, while leaving out another. Co-mingling objects from many remotes into one repository can reveal which remotes are responsible for increasing the repository's size (considering the size of the origin as the baseline).
Conclusion
In this article, we learned about the Git Rev List. Let us recap the points we discussed throughout the article:
- Git rev-list is a very useful command, due to its ability to create and navigate commit ancestry graphs, which we use to fetch the list of commit objects in reverse sequential order.
- The Git rev list basically, lists the commits that can be reached by following the provided parent links mentioned in the commit(s), but does not include the commits that can be reached from the commit(s) that are provided with a ^ in front of them.
- By default, the result is presented in reverse sequential order.
- The following command for Git Rev List is $ git rev-list hello world ^def.
- We can also use the <commit1>..<commit2> notation, in place of <commit1> ^<commit2>.
- <commit1>…<commit2> is another unique notation that is helpful for merging.
- We have seen the synopsis of the Git rev-list.
- Git rev list consists of a wide range of options that allow it to be utilized by commands as different as git repack and git bisect.
- Git rev list consists of options types such as Commit Limiting, History Simplification, Bisection Helpers, Commit Ordering, Object Traversal, and Commit Formatting. If you want to read about them in detail you can refer to Git-rev-list-options.
- Then we have seen different examples of Git rev-list.