DEV Community

Cover image for 100 Days of DevOps and Cloud (AWS), Day 28: Cherry-Pick Takes One Commit, and the Tag Is the Address
Nnamdi Felix Ibe
Nnamdi Felix Ibe

Posted on

100 Days of DevOps and Cloud (AWS), Day 28: Cherry-Pick Takes One Commit, and the Tag Is the Address

Both of today's tasks came down to being precise about exactly what you are moving and exactly where it is going. In one, the answer is a single commit out of a branch full of them. In the other, it is an image whose destination is hidden somewhere you would not think to look.

One Git task, one AWS task. Cherry-pick one commit onto master, then create a private ECR repository and push a Docker image to it. The tasks come from the KodeKloud Engineer platform.

Cherry-pick: one commit, not the branch it came from

Merging takes a whole branch. Sometimes you want one commit out of it and nothing else — the fix that has to ship today, sitting on a feature branch that is nowhere near ready.

cd /usr/src/kodekloudrepos/<repo>

git branch -a
git log --oneline <feature-branch>
git show <commit-id>            # confirm it is the change you actually mean

git checkout master
git cherry-pick <commit-id>

git log --oneline
git status
git push origin master
Enter fullscreen mode Exit fullscreen mode

The detail worth understanding is what actually happens. Cherry-pick does not move the commit. It copies the change, and the result gets a brand-new hash because a commit's identity includes its parent, and the parent is different now. The original stays exactly where it was on the source branch, untouched.

That has a consequence people meet the hard way. If you cherry-pick a fix onto master and then later merge the whole feature branch, Git is looking at two different commits containing the same diff. It frequently conflicts on the second one, and the conflict is confusing precisely because both sides look correct. Pick or merge. Try not to do both to the same change.

Two habits worth forming. Cherry-pick applies onto the branch you are standing on, exactly like merge, so git branch --show-current before you run it is two seconds well spent. And when you take several commits at once, order matters — git cherry-pick A B C applies them in the order given, and picking a commit whose dependency you skipped produces conflicts that look inexplicable until you notice the gap.

There is also a wider signal here. Cherry-picking is a precision instrument, and reaching for it constantly usually means the branching model is fighting you rather than helping.

ECR: docker push has nowhere to put an address

The AWS task was creating a private ECR repository and pushing an image into it. The commands are unremarkable right up until the one that actually matters.

export AWS_DEFAULT_REGION=us-east-1
aws sts get-caller-identity

aws ecr create-repository --repository-name xfusion-ecr --region us-east-1

REPO_URI=$(aws ecr describe-repositories \
  --repository-names xfusion-ecr \
  --query 'repositories[0].repositoryUri' --output text)
echo $REPO_URI
# <account-id>.dkr.ecr.us-east-1.amazonaws.com/xfusion-ecr
Enter fullscreen mode Exit fullscreen mode

Then authenticate, build, tag, and push:

aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin $REPO_URI

cd /root/pyapp
docker build -t xfusion-ecr:latest .

docker tag xfusion-ecr:latest $REPO_URI:latest
docker push $REPO_URI:latest
Enter fullscreen mode Exit fullscreen mode

Look closely at docker push. It takes no destination. There is no --registry flag, no target argument. The tag is the address. That docker tag line is not a cosmetic labelling step you can skip — it is the step that tells Docker which registry the image belongs to. Push a plain local name, and Docker assumes Docker Hub, tries there, and rejects you with an error that sounds like a permissions problem.

Once that clicks, the repository URI stops looking like noise and starts reading like what it is: <account-id>.dkr.ecr.<region>.amazonaws.com/<repo>. Your account, your region, your repository. An address, in address order.

Two security details in that login line. ECR credentials are temporaryget-login-password mints a token valid for about twelve hours, which is why it is piped straight into docker login rather than saved anywhere. And --password-stdin keeps that token out of your shell history and out of the process list, where --password on the command line would put it in both.

One last thing worth saying out loud, because it causes real problems later: latest is not a pointer that updates itself. It is a tag string like any other, and it moves only because you re-tag and re-push. Building a deployment on latest means you cannot reliably say what is running. Pin a digest or a real version tag for anything that matters.

Precision about what and where

Cherry-pick is the answer to "which change, exactly." The image tag is the answer to "which registry, exactly." Both tasks punished vagueness in the same way, by doing something plausible with the wrong target rather than refusing outright.

So here is the Day 28 question. When you move something — a change, an artifact, a config — is the destination stated somewhere you can read, or is it just implied by whatever the default happens to be?

Day 28 down. Seventy-two to go.

Top comments (0)