Skip to content

Pick

Overview

Among all interactive rebase commands, the pick action is certainly the most that seems to be the most neutral.

It does nothing special except telling Git to preserve the commit as it is, without any change.

Well, this is mostly true except for the last part: "without any change".

If the pick command won't touch your commit itself, you will anyway impact the overall log history if you simply reorder commits.

Setup playground

Create a simple playground repository to play with the pick command. From the course repository root, run the following command in your shell:

bash
./scripts/create-playground.sh rebase-int_pick

This will create a simple repository for a Java implementation of a class that compute Fibonacci suite.

WARNING

In the command bellow, make sure to use the SHA1 in your repository that match the commit message, not the one from this example.

Check your playground log history.

bash
cd ./playgrounds/rebase-int_pick ; git log --oneline
8ecabd1 (HEAD -> main) fix computation
b33b771 add debug
1e7f4d3 implement Fibonacci computation
e51f8b8 debug array print
b09aaf1 implement the print of list
b0caf35 draft for main class and internal API

Activity goal

In this activity, you will only use the "pick" action.

This action won't do anything to a commit content and will simply preserve the commit content while rewriting the log history one commit after the other.

At the end, you will see that the log history is exactly the same, except that each commit hash (SHA1) has been recomputed.

An activity to do nothing

Now, let's launch an interactive rebase to rewrite history log on last 5 commits.

bash
git rebase --interactive HEAD~5
console
hint: Waiting for your editor to close the file...

In parallel your code editor should open with the following content:

git-rebase
pick b09aaf1 # implement the print of list
pick e51f8b8 # debug array print
pick 1e7f4d3 # implement Fibonacci computation
pick b33b771 # add debug
pick 8ecabd1 # fix computation

# Rebase b0caf35..8ecabd1 onto b0caf35 (5 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
#         create a merge commit using the original merge commit's
#         message (or the oneline, if no original merge commit was
#         specified); use -c <commit> to reword the commit message
# u, update-ref <ref> = track a placeholder for the <ref> to be updated
#                       to this position in the new commits. The <ref> is
#                       updated at the end of the rebase
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

What you see is a traditional rebase set of commands that is split in two groups:

  1. On top you have proper interactive rebase commands
  2. A second part, all lines prefixed with a "#" are just comments that will be ignored by Git.

The first part contains three columns:

  1. A command for Git interactive rebase;
  2. The hash (SHA1) of the commit
  3. A separating "#" followed by the commit message

The second part is mostly an inline help to recall you all available commands that can be applied on each commit.

Note

You will certainly remark that each commit is assigned the pick command by default.

If you just close your editor now, rebase will just complete without anything special being done.

Just to prove the point, replace at least one "pick" with a simple "p" command, save, and close your editor.

For example, "p" replaces the long form command in highlighted lines below:

git-rebase
pick b09aaf1 # implement the print of list
p    e51f8b8 # debug array print
pick 1e7f4d3 # implement Fibonacci computation
p    b33b771 # add debug
pick 8ecabd1 # fix computation

Well, you shell shoud now just mention:

console
Successfully rebased and updated refs/heads/main.

You can check again log history to verify that nothing has changed. You will see the very same set of commit, in the very same order.

We did nothing.

What we learned

The pick command is a basic interactive rebase action that just instruct Git to just do preserve a specific commit.

As this is a neutral action it is also the default action assigned to a commit when interactive rebase is started.

Why would you need a command to tell Git to preserve a commit?

There a small twist to this neutrality: pick is really preserving a commit without any change, but you have the possibility to change order of rows in the rebase command file.

And this enable to change commit order while preserving their content.

For more details check the section about reorder command.