SlideShare ist ein Scribd-Unternehmen logo
1 von 70
Downloaden Sie, um offline zu lesen
Writing Commits for
You,
Your Friends,
and Your Future Self
Victoria Dye
Who am I?
Name - Victoria Dye (@vdye)
Occupation - Software Developer
Company - GitHub
Where I contribute - Git
I. Context
II. Writing Good Commits
III. Performing Commit-by-Commit Reviews
IV. Utilizing the Commit History
I. Context
II. Writing Good Commits
III. Performing Commit-by-Commit Reviews
IV. Utilizing the Commit History
What is a commit (and why should I care)?
[Commits] are snapshots of your entire repository at
specific times…based around logical units of change.
Over time, commits should tell a story of the
history of your repository and how it came to be
the way that it currently is.[1]
[1] https://github.com/git-guides/git-commit (2022 Mar 10)
Number of commits in git[1]
- 66,016
Lines of text (code, documentation) in the repository - 1,412,339
Word count of non-merge commit messages - 3,292,050
Word count of War and Peace (English translation)[2]
- 562,493
[1] As of 715d08a9e5 (The eighth batch, 2022-02-25)
[2] https://www.gutenberg.org/files/2600/2600-h/2600-h.htm (last accessed: Mar 18, 2022)
What do you mean by “you, your friends, and
your future self”?
You
…you (in the present)
Your Friends
reviewers,
co-contributors
Your Future Self
someone reading your
code in the future
Writing good commits for…
You
➢ “This is a huge project, where do I start?”
Your friends
➢ “How do I review this?”
Your future self
➢ “What was this code supposed to do?”
I. Context
II. Writing Good Commits
III. Performing Commit-by-Commit Reviews
IV. Debugging with the Commit History
Guidelines for writing good commits
1. Outline your changes as a narrative structure
2. Break your changes into small, atomic increments
3. Use the commit message to explain “what” and “why”
Guidelines for writing good commits
1. Outline your changes as a narrative structure
2. Break your changes into small, atomic increments
3. Use the commit message to explain “what” and “why”
You
I’ll just hack at login &
logout functions until I get
something to compile…
It’s working locally! Now
to add tests so I don’t get
dinged on my review…
I’ll just hack at login &
logout functions until I get
something to compile…
You
It’s working locally! Now
to add tests so I don’t get
dinged on my review…
I’ll just hack at login &
logout functions until I get
something to compile…
You
But it works on my
machine!! *sigh*
It’s working locally! Now
to add tests so I don’t get
dinged on my review…
I’ll just hack at login &
logout functions until I get
something to compile…
You
Why didn’t I see that
before! That should fix it.
But it works on my
machine!! *sigh*
It’s working locally! Now
to add tests so I don’t get
dinged on my review…
I’ll just hack at login &
logout functions until I get
something to compile…
You
Why didn’t I see that
before! That should fix it.
But it works on my
machine!! *sigh*
It’s working locally! Now
to add tests so I don’t get
dinged on my review…
I’ll just hack at login &
logout functions until I get
something to compile…
I fixed everything
mentioned in the review,
time to merge!
You
Your Reviewer
Half of the functions
called here aren’t
implemented. Maybe they
show up later?
Your Reviewer
I think this function was
called in the first commit?
I’ll just assume it’s called
correctly.
Half of the functions
called here aren’t
implemented. Maybe they
show up later?
Your Reviewer
This is a ton of tests, but I
guess that makes sense
given login/logout is such
a core functionality.
I think this function was
called in the first commit?
I’ll just assume it’s called
correctly.
Half of the functions
called here aren’t
implemented. Maybe they
show up later?
Your Reviewer
I’ll just skip these. CI
passes now, so one of
these fixes must work.
This is a ton of tests, but I
guess that makes sense
given login/logout is such
a core functionality.
I think this function was
called in the first commit?
I’ll just assume it’s called
correctly.
Half of the functions
called here aren’t
implemented. Maybe they
show up later?
Your Reviewer
I’ll just skip these. CI
passes now, so one of
these fixes must work.
This is a ton of tests, but I
guess that makes sense
given login/logout is such
a core functionality.
I think this function was
called in the first commit?
I’ll just assume it’s called
correctly.
Half of the functions
called here aren’t
implemented. Maybe they
show up later?
There’s a lot of stuff
updated here. I’ll skip this
and assume this matches
the review feedback?
Narrative structure
“Good narrative structure is about presenting the plot
and story elements to allow readers to understand
what is happening and what it all means.”[1]
[1] https://blog.reedsy.com/guide/story-structure/ (last accessed: Mar 14, 2022)
Narrative structure
No one-size-fits-all
DO
Create an outline, include it in the
PR description or “cover letter”
Stay on-topic
DON’T
Put partial or independent
changes together in a commit
“Correct” a commit in a later
commit
Most importantly, tell your story
Guidelines for writing good commits
1. Outline your changes as a narrative structure
2. Break your changes into small, atomic increments
3. Use the commit message to explain “what” and “why”
Outline
1. Setup
a. Fix CI bug
2. Implement feature
a. Implement login
b. Implement logout
3. Test
4. Document
build.yml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
src/common.code | 81 ++--
src/login.code | 574++++++++++++++++++++++++++++
src/users.code | 126++++++
test/login.test | 362++++++++++++++++++
new-site.build | 22 +-
5 files changed, 1146 insertions(+), 19 deletions(-)
src/common.code | 135++++++--
src/logout.code | 126++++++
test/logout.test | 362++++++++++++++++++
3 files changed, 609 insertions(+), 14 deletions(-)
test/common.code | 57+++++++++++
test/pictures.test | 39+++++++-
test/polls.test | 28++++--
test/text-posts.test | 45++++++---
test/videos.test | 17++-
5 files changed, 164 insertions(+), 22 deletions(-)
docs/login-logout.md | 229++++++++++++
1 file changed, 229 insertions(+)
build.yml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
src/common.code | 81 ++--
src/login.code | 574++++++++++++++++++++++++++++
src/users.code | 126++++++
test/login.test | 362++++++++++++++++++
new-site.build | 22 +-
5 files changed, 1146 insertions(+), 19 deletions(-)
src/common.code | 135++++++--
src/logout.code | 126++++++
test/logout.test | 362++++++++++++++++++
3 files changed, 609 insertions(+), 14 deletions(-)
test/common.code | 57+++++++++++
test/pictures.test | 39+++++++-
test/polls.test | 28++++--
test/text-posts.test | 45++++++---
test/videos.test | 17++-
5 files changed, 164 insertions(+), 22 deletions(-)
docs/login-logout.md | 229++++++++++++
1 file changed, 229 insertions(+)
build.yml | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
src/common.code | 81 ++--
src/login.code | 574++++++++++++++++++++++++++++
src/users.code | 126++++++
test/login.test | 362++++++++++++++++++
new-site.build | 22 +-
5 files changed, 1146 insertions(+), 19 deletions(-)
src/common.code | 135++++++--
src/logout.code | 126++++++
test/logout.test | 362++++++++++++++++++
3 files changed, 609 insertions(+), 14 deletions(-)
test/common.code | 57+++++++++++
test/pictures.test | 39+++++++-
test/polls.test | 28++++--
test/text-posts.test | 45++++++---
test/videos.test | 17++-
5 files changed, 164 insertions(+), 22 deletions(-)
docs/login-logout.md | 229++++++++++++
1 file changed, 229 insertions(+)
src/common.code | 81 ++--
src/login.code | 574++++++++++++++++++++++++++++
src/users.code | 126++++++
test/login.test | 362++++++++++++++++++
new-site.build | 22 +-
5 files changed, 1146 insertions(+), 19 deletions(-)
Atomic
Every commit is an independent unit
The repo is stable after every commit
Each commit does one thing
Change stack has minimal depth
Small
+ int get_user(UUID user_id)
+ {
+ ...
+ }
+ int login(uuid)
+ {
+ ...
+ exists = get_user(uuid);
+ ...
+ }
Commit A
Commit B
Guidelines for writing good commits
1. Outline your changes as a narrative structure
2. Break your changes into small, atomic increments
3. Use the commit message to explain “what” and “why”
commit <SHA>
Author: Jeff Hostetler <jeffhost@microsoft.com>
Date: Mon Oct 4 22:29:03 2021 +0000
t/perf/perf-lib.sh: remove test_times.* at the end test_perf_()
Teach test_perf_() to remove the temporary test_times.* files
at the end of each test.
test_perf_() runs a particular GIT_PERF_REPEAT_COUNT times and
creates
./test_times.[123...]. It then uses a perl script to find the
minimum
over "./test_times.*" (note the wildcard) and writes that time to
"test-results/<testname>.<testnumber>.result".
If the repeat count is changed during the pXXXX test script, stale
test_times.* files (from previous steps) may be included in the min()
computation. For example:
...
GIT_PERF_REPEAT_COUNT=3 
test_perf "status" "
git status
"
GIT_PERF_REPEAT_COUNT=1 
test_perf "checkout other" "
git checkout other
"
...
The time reported in the summary for "XXXX.2 checkout other" would
be "min( checkout[1], status[2], status[3] )".
We prevent that error by removing the test_times.* files at the end
of
each test.
commit <SHA>
Author: Victoria Dye <vdye@github.com>
Date: Fri Dec 17 10:26:59 2021 -0500
Make error text more helpful
What
High-level intent of the commit (what
does this accomplish?)
Explanation of the implementation
(what did you do to accomplish your
goal?)
Why
Context for your implementation
(why does the code do what it does
now?)
Justification for the change (why is
this change being made?)
commit <SHA>
Author: Jeff Hostetler <jeffhost@microsoft.com>
Date: Mon Oct 4 22:29:03 2021 +0000
t/perf/perf-lib.sh: remove test_times.* at the end test_perf_()
Teach test_perf_() to remove the temporary test_times.* files
at the end of each test.
test_perf_() runs a particular GIT_PERF_REPEAT_COUNT times and
creates
./test_times.[123...]. It then uses a perl script to find the
minimum
over "./test_times.*" (note the wildcard) and writes that time to
"test-results/<testname>.<testnumber>.result".
If the repeat count is changed during the pXXXX test script, stale
test_times.* files (from previous steps) may be included in the min()
computation. For example:
...
GIT_PERF_REPEAT_COUNT=3 
test_perf "status" "
git status
"
GIT_PERF_REPEAT_COUNT=1 
test_perf "checkout other" "
git checkout other
"
...
The time reported in the summary for "XXXX.2 checkout other" would
be "min( checkout[1], status[2], status[3] )".
We prevent that error by removing the test_times.* files at the end
of
each test.
Implementation
Intent
Context
Justification
What
High-level intent of the commit (what
does this accomplish?)
Explanation of the implementation
(what did you do to accomplish your
goal?)
Why
Justification for the change (why is
this needed?)
Context for your implementation
(why is it implemented this way?)
Most commits only (lightly) cover these
commit <SHA>
Author: Victoria Dye <vdye@github.com>
Date: Fri Dec 17 10:26:59 2021 -0500
Make error text more helpful Intent
commit <SHA>
Author: Victoria Dye <vdye@github.com>
Date: Fri Dec 17 10:26:59 2021 -0500
Make error text more helpful Intent
$ ./git-portable.sh invalid-command
Not a valid command: invalid-command
$ ./gitportable.sh
Not a valid command:
$ ./git-portable.sh invalid-command
Not a valid command: invalid-command
$ ./gitportable.sh
Please specify a command
What it’s actually doing
commit <SHA>
Author: Victoria Dye <vdye@github.com>
Date: Fri Dec 17 10:26:59 2021 -0500
git-portable.sh: make error text more helpful
When provided with incorrect argument, return a message more indicative of
the cause of the error.
If a user did not provide an argument to ‘git-portable.sh’, the error
message returned would be:
$ ./git-portable.sh
Not a valid command:
This does not clearly indicate that the problem is that ‘git-portable.sh’
must be called with a subcommand (e.g., ./git-portable.sh install).
To guide the user towards the correct usage, instead print “Please specify a
command” when no subcommand is specified. Implementation
Intent
Context
Justification
commit <SHA>
Author: Victoria Dye <vdye@github.com>
Date: Fri Dec 17 10:26:59 2021 -0500
git-portable.sh: make error text more helpful
The message “Not a valid command: <invalid command>” is
intended to notify the user that their subcommand is invalid.
However, when no subcommand is given, the "empty" subcommand
results in the same message: "Not a valid command:". This does
not clearly guide the user to the correct behavior, so print
"Please specify a command" when no subcommand is specified. Implementation
Intent
Context
Justification
Recap: guidelines for writing good commits
1. Outline your changes as a narrative structure
→ Takeway: guides you & your reviewer through changes
2. Break your changes into small, atomic increments
→ Takeaway: makes review as efficient as possible
3. Use the commit message to explain “what” and “why”
→ Takeaway: lets readers understand the code how you do
But how do I actually do this?
git commit --amend
git commit --fixup <target>
git rebase -i --keep-base <main>
git reset <target>
Re-committing from scratch? Adjusting what you have?
git reset <target>
Re-committing from scratch?
● The commits are “undone”.
● Your files don’t change!
git commit --amend
git commit --fixup <target>
git rebase -i --keep-base <main>
Adjusting what you have?
● commit --amend - reword and
add changes to your latest
commit
● commit --fixup - create a
commit with a special message
that, when rebased, combines
with the target (“squashes”)
● rebase -i - reorder, reword,
drop, squash, etc. a list of
commits
git commit --amend
git commit --fixup <target>
git rebase -i --keep-base <main>
git reset <target>
Re-committing from scratch? Adjusting what you have?
I. Context
II. Writing Good Commits
III. Performing Commit-by-Commit Reviews
IV. Utilizing the Commit History
Reviewing commit-by-commit
Bugfixes
Tests
Refactor
Reviewing commit-by-commit
commit <SHA>
Author: Victoria Dye <vdye@github.com>
Date: Fri Jan 28 10:50:27 2022 -0500
sparse-index: prevent repo root from becoming sparse
Prevent the repository root from being collapsed into a sparse directory by
treating an empty path as "inside the sparse-checkout". When collapsing a
sparse index (e.g. in 'git sparse-checkout reapply'), the root directory
typically could not become a sparse directory due to the presence of in-cone
root-level files and directories. However, if no such in-cone files or
directories were present, there was no explicit check signaling that the
"repository root path" (an empty string, in the case of
'convert_to_sparse(...)') was in-cone, and a sparse directory index entry
would be created from the repository root directory.
The documentation in Documentation/git-sparse-checkout.txt explicitly states
that the files in the root directory are expected to be in-cone for a
cone-mode sparse-checkout. Collapsing the root into a sparse directory entry
violates that assumption, as sparse directory entries are expected to be
that the files in the root directory are expected to be in-cone for a
cone-mode sparse-checkout. Collapsing the root into a sparse directory entry
violates that assumption, as sparse directory entries are expected to be
outside the sparse cone and have SKIP_WORKTREE enabled. This invalid state
in turn causes issues with commands that interact with the index, e.g.
'git status'.
Treating an empty (root) path as in-cone prevents the creation of a root
sparse directory in 'convert_to_sparse(...)'. Because the repository root is
otherwise never compared with sparse patterns (in both cone-mode and
non-cone sparse-checkouts), the new check does not cause additional changes
to how sparse patterns are applied.
Intent
Implementation
Context
Justification
Reviewing commit-by-commit
Implementation
Prevent the repository root
from being collapsed into a
sparse directory by treating
an empty path as "inside the
sparse-checkout".
diff --git a/dir.c b/dir.c
index d91295f2bc..a136377eb4 100644
--- a/dir.c
+++ b/dir.c
@@ -1463,10 +1463,11 @@ static int path_in_sparse_checkout_1(const char
*path,
const char *end, *slash;
/*
- * We default to accepting a path if there are no patterns or
- * they are of the wrong type.
+ * We default to accepting a path if the path is empty, there are no
+ * patterns, or the patterns are of the wrong type.
*/
- if (init_sparse_checkout_patterns(istate) ||
+ if (!*path ||
+ init_sparse_checkout_patterns(istate) ||
(require_cone_mode &&
!istate->sparse_checkout_patterns->use_cone_patterns))
return 1;
I. Context
II. Writing Good Commits
III. Performing Commit-by-Commit Reviews
IV. Utilizing the Commit History
git bisect
Narrow down the source of a bug to a specific commit
Last good
deployment
Failed
deployment
The bug
git bisect start <bad> <good>
Working?
Working?
git bisect good
Working?
Working?
git bisect bad
Working?
Working?
git bisect bad
🎉 Found the bug! 🎉
…but why did it happen
in the first place?
git blame
Find out which commit last changed a
line of code
Search commits by file, change
location, and/or message
git log
$ git blame -s my-file.py
abd52642da46 my-file.py 1) import os
603ab927a0dd oldname.py 3) import re
603ab927a0dd oldname.py 4)
603ab927a0dd oldname.py 5) print(“Hello world”)
abd52642da46 my-file.py 5) print(os.stat(“README”))
...
$ git log --oneline -- my-file.py
abd52642da46 my-file.py: add README stat printout
7392d7dbb9ae my-file.py: rename from oldname.py
603ab927a0dd oldname.py: create printout script
...
$ git log --oneline
09823ba09de1 README.md: update maintainer contact
abd52642da46 my-file.py: add README stat printout
7392d7dbb9ae my-file.py: rename from oldname.py
5ad823d1bc48 test.py: commonize test setup
603ab927a0dd oldname.py: create printout script
...
I. 🎉 Context 🎉
II. ✨ Writing Good Commits ✨
III. 🎊 Performing Commit-by-Commit Reviews 🎊
IV. 🥳 Utilizing the Commit History 🥳
Remember these things!
Git commits contextualize your code for a broader audience.
You can improve the quality of your commits today by organizing a narrative,
making changes small & atomic, and explaining “what” & “why”.
Spending time on writing high-quality commits is helpful for anyone and
everyone involved in your open- or closed-source project.
Questions?
Download these slides: https://vdye.github.io/2022/OS101-Writing-Commits.pdf

Weitere ähnliche Inhalte

Was ist angesagt?

Managing dependencies with gradle
Managing dependencies with gradleManaging dependencies with gradle
Managing dependencies with gradleLiviu Tudor
 
Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...
Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...
Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...Edureka!
 
Exploring the GitHub Service Universe
Exploring the GitHub Service UniverseExploring the GitHub Service Universe
Exploring the GitHub Service UniverseBjörn Kimminich
 
はじめての JFrog Artifactory
はじめての JFrog Artifactoryはじめての JFrog Artifactory
はじめての JFrog ArtifactoryTsuyoshi Miyake
 
13 practical tips for writing secure golang applications
13 practical tips for writing secure golang applications13 practical tips for writing secure golang applications
13 practical tips for writing secure golang applicationsKarthik Gaekwad
 
GitLab for CI/CD process
GitLab for CI/CD processGitLab for CI/CD process
GitLab for CI/CD processHYS Enterprise
 
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...Andrew Phillips
 
Jenkins vs GitLab CI
Jenkins vs GitLab CIJenkins vs GitLab CI
Jenkins vs GitLab CICEE-SEC(R)
 
Git essential training & sharing self
Git essential training & sharing selfGit essential training & sharing self
Git essential training & sharing selfChen-Tien Tsai
 
How Git and Gerrit make you more productive
How Git and Gerrit make you more productiveHow Git and Gerrit make you more productive
How Git and Gerrit make you more productiveKarsten Dambekalns
 
GitLab as an Alternative Development Platform for Github.com
GitLab as an Alternative Development Platform for Github.comGitLab as an Alternative Development Platform for Github.com
GitLab as an Alternative Development Platform for Github.comB1 Systems GmbH
 
Master Continuous Delivery with CloudBees Jenkins Platform
Master Continuous Delivery with CloudBees Jenkins PlatformMaster Continuous Delivery with CloudBees Jenkins Platform
Master Continuous Delivery with CloudBees Jenkins Platformdcjuengst
 
ESE 2010: Using Git in Eclipse
ESE 2010: Using Git in EclipseESE 2010: Using Git in Eclipse
ESE 2010: Using Git in EclipseChris Aniszczyk
 
What is Git | What is GitHub | Git Tutorial | GitHub Tutorial | Devops Tutori...
What is Git | What is GitHub | Git Tutorial | GitHub Tutorial | Devops Tutori...What is Git | What is GitHub | Git Tutorial | GitHub Tutorial | Devops Tutori...
What is Git | What is GitHub | Git Tutorial | GitHub Tutorial | Devops Tutori...Edureka!
 
DevOps with OpenShift - Fabien Dupont - ManageIQ Design Summit 2016
DevOps with OpenShift - Fabien Dupont - ManageIQ Design Summit 2016DevOps with OpenShift - Fabien Dupont - ManageIQ Design Summit 2016
DevOps with OpenShift - Fabien Dupont - ManageIQ Design Summit 2016ManageIQ
 
Cloud-Native CI/CD on Kubernetes with Tekton Pipelines
Cloud-Native CI/CD on Kubernetes with Tekton PipelinesCloud-Native CI/CD on Kubernetes with Tekton Pipelines
Cloud-Native CI/CD on Kubernetes with Tekton PipelinesNikhil Thomas
 
A painless self-hosted Git service: Gitea
A painless self-hosted Git service: GiteaA painless self-hosted Git service: Gitea
A painless self-hosted Git service: GiteaBo-Yi Wu
 

Was ist angesagt? (20)

Managing dependencies with gradle
Managing dependencies with gradleManaging dependencies with gradle
Managing dependencies with gradle
 
Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...
Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...
Git Tutorial | Git Basics - Branching, Merging, Rebasing | Learn Git | DevOps...
 
Exploring the GitHub Service Universe
Exploring the GitHub Service UniverseExploring the GitHub Service Universe
Exploring the GitHub Service Universe
 
はじめての JFrog Artifactory
はじめての JFrog Artifactoryはじめての JFrog Artifactory
はじめての JFrog Artifactory
 
13 practical tips for writing secure golang applications
13 practical tips for writing secure golang applications13 practical tips for writing secure golang applications
13 practical tips for writing secure golang applications
 
Git best practices workshop
Git best practices workshopGit best practices workshop
Git best practices workshop
 
GitLab for CI/CD process
GitLab for CI/CD processGitLab for CI/CD process
GitLab for CI/CD process
 
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...
Continuous Delivery NYC: From GitOps to an adaptable CI/CD Pattern for Kubern...
 
Jenkins vs GitLab CI
Jenkins vs GitLab CIJenkins vs GitLab CI
Jenkins vs GitLab CI
 
Git essential training & sharing self
Git essential training & sharing selfGit essential training & sharing self
Git essential training & sharing self
 
How Git and Gerrit make you more productive
How Git and Gerrit make you more productiveHow Git and Gerrit make you more productive
How Git and Gerrit make you more productive
 
GitLab as an Alternative Development Platform for Github.com
GitLab as an Alternative Development Platform for Github.comGitLab as an Alternative Development Platform for Github.com
GitLab as an Alternative Development Platform for Github.com
 
Gerrit Workshop
Gerrit WorkshopGerrit Workshop
Gerrit Workshop
 
Master Continuous Delivery with CloudBees Jenkins Platform
Master Continuous Delivery with CloudBees Jenkins PlatformMaster Continuous Delivery with CloudBees Jenkins Platform
Master Continuous Delivery with CloudBees Jenkins Platform
 
Introducing GitLab
Introducing GitLabIntroducing GitLab
Introducing GitLab
 
ESE 2010: Using Git in Eclipse
ESE 2010: Using Git in EclipseESE 2010: Using Git in Eclipse
ESE 2010: Using Git in Eclipse
 
What is Git | What is GitHub | Git Tutorial | GitHub Tutorial | Devops Tutori...
What is Git | What is GitHub | Git Tutorial | GitHub Tutorial | Devops Tutori...What is Git | What is GitHub | Git Tutorial | GitHub Tutorial | Devops Tutori...
What is Git | What is GitHub | Git Tutorial | GitHub Tutorial | Devops Tutori...
 
DevOps with OpenShift - Fabien Dupont - ManageIQ Design Summit 2016
DevOps with OpenShift - Fabien Dupont - ManageIQ Design Summit 2016DevOps with OpenShift - Fabien Dupont - ManageIQ Design Summit 2016
DevOps with OpenShift - Fabien Dupont - ManageIQ Design Summit 2016
 
Cloud-Native CI/CD on Kubernetes with Tekton Pipelines
Cloud-Native CI/CD on Kubernetes with Tekton PipelinesCloud-Native CI/CD on Kubernetes with Tekton Pipelines
Cloud-Native CI/CD on Kubernetes with Tekton Pipelines
 
A painless self-hosted Git service: Gitea
A painless self-hosted Git service: GiteaA painless self-hosted Git service: Gitea
A painless self-hosted Git service: Gitea
 

Ähnlich wie Writing Commits for You, Your Friends, and Your Future Self

Static Code Analysis PHP[tek] 2023
Static Code Analysis PHP[tek] 2023Static Code Analysis PHP[tek] 2023
Static Code Analysis PHP[tek] 2023Scott Keck-Warren
 
Web Development Foundation & Team Collaboration
Web Development Foundation & Team CollaborationWeb Development Foundation & Team Collaboration
Web Development Foundation & Team CollaborationSupanat Potiwarakorn
 
Software Testing
Software TestingSoftware Testing
Software Testingsuperphly
 
A tale of two proxies
A tale of two proxiesA tale of two proxies
A tale of two proxiesSensePost
 
Serverless in production, an experience report (Going Serverless, 28 Feb 2018)
Serverless in production, an experience report (Going Serverless, 28 Feb 2018)Serverless in production, an experience report (Going Serverless, 28 Feb 2018)
Serverless in production, an experience report (Going Serverless, 28 Feb 2018)Domas Lasauskas
 
Monitoring your Python with Prometheus (Python Ireland April 2015)
Monitoring your Python with Prometheus (Python Ireland April 2015)Monitoring your Python with Prometheus (Python Ireland April 2015)
Monitoring your Python with Prometheus (Python Ireland April 2015)Brian Brazil
 
Making the most of your Test Suite
Making the most of your Test SuiteMaking the most of your Test Suite
Making the most of your Test Suiteericholscher
 
Python tools for testing web services over HTTP
Python tools for testing web services over HTTPPython tools for testing web services over HTTP
Python tools for testing web services over HTTPMykhailo Kolesnyk
 
20141210 rakuten techtalk
20141210 rakuten techtalk20141210 rakuten techtalk
20141210 rakuten techtalkHiroshi SHIBATA
 
Recent Updates at Embulk Meetup #3
Recent Updates at Embulk Meetup #3Recent Updates at Embulk Meetup #3
Recent Updates at Embulk Meetup #3Muga Nishizawa
 
Understanding Framework Architecture using Eclipse
Understanding Framework Architecture using EclipseUnderstanding Framework Architecture using Eclipse
Understanding Framework Architecture using Eclipseanshunjain
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)True-Vision
 
Automated testing with Cypress
Automated testing with CypressAutomated testing with Cypress
Automated testing with CypressYong Shean Chong
 
Serverless in production, an experience report (LNUG)
Serverless in production, an experience report (LNUG)Serverless in production, an experience report (LNUG)
Serverless in production, an experience report (LNUG)Yan Cui
 
Effizientere WordPress-Plugin-Entwicklung mit Softwaretests
Effizientere WordPress-Plugin-Entwicklung mit SoftwaretestsEffizientere WordPress-Plugin-Entwicklung mit Softwaretests
Effizientere WordPress-Plugin-Entwicklung mit SoftwaretestsDECK36
 

Ähnlich wie Writing Commits for You, Your Friends, and Your Future Self (20)

Static Code Analysis PHP[tek] 2023
Static Code Analysis PHP[tek] 2023Static Code Analysis PHP[tek] 2023
Static Code Analysis PHP[tek] 2023
 
Web Development Foundation & Team Collaboration
Web Development Foundation & Team CollaborationWeb Development Foundation & Team Collaboration
Web Development Foundation & Team Collaboration
 
Software Testing
Software TestingSoftware Testing
Software Testing
 
A tale of two proxies
A tale of two proxiesA tale of two proxies
A tale of two proxies
 
Serverless in production, an experience report (Going Serverless, 28 Feb 2018)
Serverless in production, an experience report (Going Serverless, 28 Feb 2018)Serverless in production, an experience report (Going Serverless, 28 Feb 2018)
Serverless in production, an experience report (Going Serverless, 28 Feb 2018)
 
Performance patterns
Performance patternsPerformance patterns
Performance patterns
 
Monitoring your Python with Prometheus (Python Ireland April 2015)
Monitoring your Python with Prometheus (Python Ireland April 2015)Monitoring your Python with Prometheus (Python Ireland April 2015)
Monitoring your Python with Prometheus (Python Ireland April 2015)
 
Making the most of your Test Suite
Making the most of your Test SuiteMaking the most of your Test Suite
Making the most of your Test Suite
 
Python tools for testing web services over HTTP
Python tools for testing web services over HTTPPython tools for testing web services over HTTP
Python tools for testing web services over HTTP
 
Why test with flex unit
Why test with flex unitWhy test with flex unit
Why test with flex unit
 
20141210 rakuten techtalk
20141210 rakuten techtalk20141210 rakuten techtalk
20141210 rakuten techtalk
 
Code Refactoring
Code RefactoringCode Refactoring
Code Refactoring
 
Recent Updates at Embulk Meetup #3
Recent Updates at Embulk Meetup #3Recent Updates at Embulk Meetup #3
Recent Updates at Embulk Meetup #3
 
Understanding Framework Architecture using Eclipse
Understanding Framework Architecture using EclipseUnderstanding Framework Architecture using Eclipse
Understanding Framework Architecture using Eclipse
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)
 
Automated testing with Cypress
Automated testing with CypressAutomated testing with Cypress
Automated testing with Cypress
 
Drupal 7 ci and testing
Drupal 7 ci and testingDrupal 7 ci and testing
Drupal 7 ci and testing
 
Serverless in production, an experience report (LNUG)
Serverless in production, an experience report (LNUG)Serverless in production, an experience report (LNUG)
Serverless in production, an experience report (LNUG)
 
Effizientere WordPress-Plugin-Entwicklung mit Softwaretests
Effizientere WordPress-Plugin-Entwicklung mit SoftwaretestsEffizientere WordPress-Plugin-Entwicklung mit Softwaretests
Effizientere WordPress-Plugin-Entwicklung mit Softwaretests
 
Refactoring a web application with Python
Refactoring a web application with PythonRefactoring a web application with Python
Refactoring a web application with Python
 

Mehr von All Things Open

Building Reliability - The Realities of Observability
Building Reliability - The Realities of ObservabilityBuilding Reliability - The Realities of Observability
Building Reliability - The Realities of ObservabilityAll Things Open
 
Modern Database Best Practices
Modern Database Best PracticesModern Database Best Practices
Modern Database Best PracticesAll Things Open
 
Open Source and Public Policy
Open Source and Public PolicyOpen Source and Public Policy
Open Source and Public PolicyAll Things Open
 
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...All Things Open
 
The State of Passwordless Auth on the Web - Phil Nash
The State of Passwordless Auth on the Web - Phil NashThe State of Passwordless Auth on the Web - Phil Nash
The State of Passwordless Auth on the Web - Phil NashAll Things Open
 
Total ReDoS: The dangers of regex in JavaScript
Total ReDoS: The dangers of regex in JavaScriptTotal ReDoS: The dangers of regex in JavaScript
Total ReDoS: The dangers of regex in JavaScriptAll Things Open
 
What Does Real World Mass Adoption of Decentralized Tech Look Like?
What Does Real World Mass Adoption of Decentralized Tech Look Like?What Does Real World Mass Adoption of Decentralized Tech Look Like?
What Does Real World Mass Adoption of Decentralized Tech Look Like?All Things Open
 
How to Write & Deploy a Smart Contract
How to Write & Deploy a Smart ContractHow to Write & Deploy a Smart Contract
How to Write & Deploy a Smart ContractAll Things Open
 
Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow
 Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow
Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlowAll Things Open
 
DEI Challenges and Success
DEI Challenges and SuccessDEI Challenges and Success
DEI Challenges and SuccessAll Things Open
 
Scaling Web Applications with Background
Scaling Web Applications with BackgroundScaling Web Applications with Background
Scaling Web Applications with BackgroundAll Things Open
 
Supercharging tutorials with WebAssembly
Supercharging tutorials with WebAssemblySupercharging tutorials with WebAssembly
Supercharging tutorials with WebAssemblyAll Things Open
 
Using SQL to Find Needles in Haystacks
Using SQL to Find Needles in HaystacksUsing SQL to Find Needles in Haystacks
Using SQL to Find Needles in HaystacksAll Things Open
 
Configuration Security as a Game of Pursuit Intercept
Configuration Security as a Game of Pursuit InterceptConfiguration Security as a Game of Pursuit Intercept
Configuration Security as a Game of Pursuit InterceptAll Things Open
 
Scaling an Open Source Sponsorship Program
Scaling an Open Source Sponsorship ProgramScaling an Open Source Sponsorship Program
Scaling an Open Source Sponsorship ProgramAll Things Open
 
Build Developer Experience Teams for Open Source
Build Developer Experience Teams for Open SourceBuild Developer Experience Teams for Open Source
Build Developer Experience Teams for Open SourceAll Things Open
 
Deploying Models at Scale with Apache Beam
Deploying Models at Scale with Apache BeamDeploying Models at Scale with Apache Beam
Deploying Models at Scale with Apache BeamAll Things Open
 
Sudo – Giving access while staying in control
Sudo – Giving access while staying in controlSudo – Giving access while staying in control
Sudo – Giving access while staying in controlAll Things Open
 
Fortifying the Future: Tackling Security Challenges in AI/ML Applications
Fortifying the Future: Tackling Security Challenges in AI/ML ApplicationsFortifying the Future: Tackling Security Challenges in AI/ML Applications
Fortifying the Future: Tackling Security Challenges in AI/ML ApplicationsAll Things Open
 
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...All Things Open
 

Mehr von All Things Open (20)

Building Reliability - The Realities of Observability
Building Reliability - The Realities of ObservabilityBuilding Reliability - The Realities of Observability
Building Reliability - The Realities of Observability
 
Modern Database Best Practices
Modern Database Best PracticesModern Database Best Practices
Modern Database Best Practices
 
Open Source and Public Policy
Open Source and Public PolicyOpen Source and Public Policy
Open Source and Public Policy
 
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...
Weaving Microservices into a Unified GraphQL Schema with graph-quilt - Ashpak...
 
The State of Passwordless Auth on the Web - Phil Nash
The State of Passwordless Auth on the Web - Phil NashThe State of Passwordless Auth on the Web - Phil Nash
The State of Passwordless Auth on the Web - Phil Nash
 
Total ReDoS: The dangers of regex in JavaScript
Total ReDoS: The dangers of regex in JavaScriptTotal ReDoS: The dangers of regex in JavaScript
Total ReDoS: The dangers of regex in JavaScript
 
What Does Real World Mass Adoption of Decentralized Tech Look Like?
What Does Real World Mass Adoption of Decentralized Tech Look Like?What Does Real World Mass Adoption of Decentralized Tech Look Like?
What Does Real World Mass Adoption of Decentralized Tech Look Like?
 
How to Write & Deploy a Smart Contract
How to Write & Deploy a Smart ContractHow to Write & Deploy a Smart Contract
How to Write & Deploy a Smart Contract
 
Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow
 Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow
Spinning Your Drones with Cadence Workflows, Apache Kafka and TensorFlow
 
DEI Challenges and Success
DEI Challenges and SuccessDEI Challenges and Success
DEI Challenges and Success
 
Scaling Web Applications with Background
Scaling Web Applications with BackgroundScaling Web Applications with Background
Scaling Web Applications with Background
 
Supercharging tutorials with WebAssembly
Supercharging tutorials with WebAssemblySupercharging tutorials with WebAssembly
Supercharging tutorials with WebAssembly
 
Using SQL to Find Needles in Haystacks
Using SQL to Find Needles in HaystacksUsing SQL to Find Needles in Haystacks
Using SQL to Find Needles in Haystacks
 
Configuration Security as a Game of Pursuit Intercept
Configuration Security as a Game of Pursuit InterceptConfiguration Security as a Game of Pursuit Intercept
Configuration Security as a Game of Pursuit Intercept
 
Scaling an Open Source Sponsorship Program
Scaling an Open Source Sponsorship ProgramScaling an Open Source Sponsorship Program
Scaling an Open Source Sponsorship Program
 
Build Developer Experience Teams for Open Source
Build Developer Experience Teams for Open SourceBuild Developer Experience Teams for Open Source
Build Developer Experience Teams for Open Source
 
Deploying Models at Scale with Apache Beam
Deploying Models at Scale with Apache BeamDeploying Models at Scale with Apache Beam
Deploying Models at Scale with Apache Beam
 
Sudo – Giving access while staying in control
Sudo – Giving access while staying in controlSudo – Giving access while staying in control
Sudo – Giving access while staying in control
 
Fortifying the Future: Tackling Security Challenges in AI/ML Applications
Fortifying the Future: Tackling Security Challenges in AI/ML ApplicationsFortifying the Future: Tackling Security Challenges in AI/ML Applications
Fortifying the Future: Tackling Security Challenges in AI/ML Applications
 
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...
Securing Cloud Resources Deployed with Control Planes on Kubernetes using Gov...
 

Kürzlich hochgeladen

Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 

Kürzlich hochgeladen (20)

Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 

Writing Commits for You, Your Friends, and Your Future Self

  • 1. Writing Commits for You, Your Friends, and Your Future Self Victoria Dye
  • 2. Who am I? Name - Victoria Dye (@vdye) Occupation - Software Developer Company - GitHub Where I contribute - Git
  • 3. I. Context II. Writing Good Commits III. Performing Commit-by-Commit Reviews IV. Utilizing the Commit History
  • 4. I. Context II. Writing Good Commits III. Performing Commit-by-Commit Reviews IV. Utilizing the Commit History
  • 5. What is a commit (and why should I care)?
  • 6. [Commits] are snapshots of your entire repository at specific times…based around logical units of change. Over time, commits should tell a story of the history of your repository and how it came to be the way that it currently is.[1] [1] https://github.com/git-guides/git-commit (2022 Mar 10)
  • 7. Number of commits in git[1] - 66,016 Lines of text (code, documentation) in the repository - 1,412,339 Word count of non-merge commit messages - 3,292,050 Word count of War and Peace (English translation)[2] - 562,493 [1] As of 715d08a9e5 (The eighth batch, 2022-02-25) [2] https://www.gutenberg.org/files/2600/2600-h/2600-h.htm (last accessed: Mar 18, 2022)
  • 8. What do you mean by “you, your friends, and your future self”?
  • 9. You …you (in the present) Your Friends reviewers, co-contributors Your Future Self someone reading your code in the future
  • 10. Writing good commits for… You ➢ “This is a huge project, where do I start?” Your friends ➢ “How do I review this?” Your future self ➢ “What was this code supposed to do?”
  • 11. I. Context II. Writing Good Commits III. Performing Commit-by-Commit Reviews IV. Debugging with the Commit History
  • 12. Guidelines for writing good commits 1. Outline your changes as a narrative structure 2. Break your changes into small, atomic increments 3. Use the commit message to explain “what” and “why”
  • 13. Guidelines for writing good commits 1. Outline your changes as a narrative structure 2. Break your changes into small, atomic increments 3. Use the commit message to explain “what” and “why”
  • 14. You I’ll just hack at login & logout functions until I get something to compile…
  • 15. It’s working locally! Now to add tests so I don’t get dinged on my review… I’ll just hack at login & logout functions until I get something to compile… You
  • 16. It’s working locally! Now to add tests so I don’t get dinged on my review… I’ll just hack at login & logout functions until I get something to compile… You
  • 17. But it works on my machine!! *sigh* It’s working locally! Now to add tests so I don’t get dinged on my review… I’ll just hack at login & logout functions until I get something to compile… You
  • 18. Why didn’t I see that before! That should fix it. But it works on my machine!! *sigh* It’s working locally! Now to add tests so I don’t get dinged on my review… I’ll just hack at login & logout functions until I get something to compile… You
  • 19. Why didn’t I see that before! That should fix it. But it works on my machine!! *sigh* It’s working locally! Now to add tests so I don’t get dinged on my review… I’ll just hack at login & logout functions until I get something to compile… I fixed everything mentioned in the review, time to merge! You
  • 20. Your Reviewer Half of the functions called here aren’t implemented. Maybe they show up later?
  • 21. Your Reviewer I think this function was called in the first commit? I’ll just assume it’s called correctly. Half of the functions called here aren’t implemented. Maybe they show up later?
  • 22. Your Reviewer This is a ton of tests, but I guess that makes sense given login/logout is such a core functionality. I think this function was called in the first commit? I’ll just assume it’s called correctly. Half of the functions called here aren’t implemented. Maybe they show up later?
  • 23. Your Reviewer I’ll just skip these. CI passes now, so one of these fixes must work. This is a ton of tests, but I guess that makes sense given login/logout is such a core functionality. I think this function was called in the first commit? I’ll just assume it’s called correctly. Half of the functions called here aren’t implemented. Maybe they show up later?
  • 24. Your Reviewer I’ll just skip these. CI passes now, so one of these fixes must work. This is a ton of tests, but I guess that makes sense given login/logout is such a core functionality. I think this function was called in the first commit? I’ll just assume it’s called correctly. Half of the functions called here aren’t implemented. Maybe they show up later? There’s a lot of stuff updated here. I’ll skip this and assume this matches the review feedback?
  • 25. Narrative structure “Good narrative structure is about presenting the plot and story elements to allow readers to understand what is happening and what it all means.”[1] [1] https://blog.reedsy.com/guide/story-structure/ (last accessed: Mar 14, 2022)
  • 27. DO Create an outline, include it in the PR description or “cover letter” Stay on-topic DON’T Put partial or independent changes together in a commit “Correct” a commit in a later commit Most importantly, tell your story
  • 28. Guidelines for writing good commits 1. Outline your changes as a narrative structure 2. Break your changes into small, atomic increments 3. Use the commit message to explain “what” and “why”
  • 29. Outline 1. Setup a. Fix CI bug 2. Implement feature a. Implement login b. Implement logout 3. Test 4. Document
  • 30. build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) src/common.code | 81 ++-- src/login.code | 574++++++++++++++++++++++++++++ src/users.code | 126++++++ test/login.test | 362++++++++++++++++++ new-site.build | 22 +- 5 files changed, 1146 insertions(+), 19 deletions(-) src/common.code | 135++++++-- src/logout.code | 126++++++ test/logout.test | 362++++++++++++++++++ 3 files changed, 609 insertions(+), 14 deletions(-) test/common.code | 57+++++++++++ test/pictures.test | 39+++++++- test/polls.test | 28++++-- test/text-posts.test | 45++++++--- test/videos.test | 17++- 5 files changed, 164 insertions(+), 22 deletions(-) docs/login-logout.md | 229++++++++++++ 1 file changed, 229 insertions(+)
  • 31. build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
  • 32. src/common.code | 81 ++-- src/login.code | 574++++++++++++++++++++++++++++ src/users.code | 126++++++ test/login.test | 362++++++++++++++++++ new-site.build | 22 +- 5 files changed, 1146 insertions(+), 19 deletions(-)
  • 33. src/common.code | 135++++++-- src/logout.code | 126++++++ test/logout.test | 362++++++++++++++++++ 3 files changed, 609 insertions(+), 14 deletions(-)
  • 34. test/common.code | 57+++++++++++ test/pictures.test | 39+++++++- test/polls.test | 28++++-- test/text-posts.test | 45++++++--- test/videos.test | 17++- 5 files changed, 164 insertions(+), 22 deletions(-)
  • 35. docs/login-logout.md | 229++++++++++++ 1 file changed, 229 insertions(+)
  • 36. build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) src/common.code | 81 ++-- src/login.code | 574++++++++++++++++++++++++++++ src/users.code | 126++++++ test/login.test | 362++++++++++++++++++ new-site.build | 22 +- 5 files changed, 1146 insertions(+), 19 deletions(-) src/common.code | 135++++++-- src/logout.code | 126++++++ test/logout.test | 362++++++++++++++++++ 3 files changed, 609 insertions(+), 14 deletions(-) test/common.code | 57+++++++++++ test/pictures.test | 39+++++++- test/polls.test | 28++++-- test/text-posts.test | 45++++++--- test/videos.test | 17++- 5 files changed, 164 insertions(+), 22 deletions(-) docs/login-logout.md | 229++++++++++++ 1 file changed, 229 insertions(+)
  • 37. src/common.code | 81 ++-- src/login.code | 574++++++++++++++++++++++++++++ src/users.code | 126++++++ test/login.test | 362++++++++++++++++++ new-site.build | 22 +- 5 files changed, 1146 insertions(+), 19 deletions(-)
  • 38. Atomic Every commit is an independent unit The repo is stable after every commit Each commit does one thing Change stack has minimal depth Small + int get_user(UUID user_id) + { + ... + } + int login(uuid) + { + ... + exists = get_user(uuid); + ... + } Commit A Commit B
  • 39. Guidelines for writing good commits 1. Outline your changes as a narrative structure 2. Break your changes into small, atomic increments 3. Use the commit message to explain “what” and “why”
  • 40. commit <SHA> Author: Jeff Hostetler <jeffhost@microsoft.com> Date: Mon Oct 4 22:29:03 2021 +0000 t/perf/perf-lib.sh: remove test_times.* at the end test_perf_() Teach test_perf_() to remove the temporary test_times.* files at the end of each test. test_perf_() runs a particular GIT_PERF_REPEAT_COUNT times and creates ./test_times.[123...]. It then uses a perl script to find the minimum over "./test_times.*" (note the wildcard) and writes that time to "test-results/<testname>.<testnumber>.result". If the repeat count is changed during the pXXXX test script, stale test_times.* files (from previous steps) may be included in the min() computation. For example: ... GIT_PERF_REPEAT_COUNT=3 test_perf "status" " git status " GIT_PERF_REPEAT_COUNT=1 test_perf "checkout other" " git checkout other " ... The time reported in the summary for "XXXX.2 checkout other" would be "min( checkout[1], status[2], status[3] )". We prevent that error by removing the test_times.* files at the end of each test. commit <SHA> Author: Victoria Dye <vdye@github.com> Date: Fri Dec 17 10:26:59 2021 -0500 Make error text more helpful
  • 41. What High-level intent of the commit (what does this accomplish?) Explanation of the implementation (what did you do to accomplish your goal?) Why Context for your implementation (why does the code do what it does now?) Justification for the change (why is this change being made?)
  • 42. commit <SHA> Author: Jeff Hostetler <jeffhost@microsoft.com> Date: Mon Oct 4 22:29:03 2021 +0000 t/perf/perf-lib.sh: remove test_times.* at the end test_perf_() Teach test_perf_() to remove the temporary test_times.* files at the end of each test. test_perf_() runs a particular GIT_PERF_REPEAT_COUNT times and creates ./test_times.[123...]. It then uses a perl script to find the minimum over "./test_times.*" (note the wildcard) and writes that time to "test-results/<testname>.<testnumber>.result". If the repeat count is changed during the pXXXX test script, stale test_times.* files (from previous steps) may be included in the min() computation. For example: ... GIT_PERF_REPEAT_COUNT=3 test_perf "status" " git status " GIT_PERF_REPEAT_COUNT=1 test_perf "checkout other" " git checkout other " ... The time reported in the summary for "XXXX.2 checkout other" would be "min( checkout[1], status[2], status[3] )". We prevent that error by removing the test_times.* files at the end of each test. Implementation Intent Context Justification
  • 43. What High-level intent of the commit (what does this accomplish?) Explanation of the implementation (what did you do to accomplish your goal?) Why Justification for the change (why is this needed?) Context for your implementation (why is it implemented this way?) Most commits only (lightly) cover these
  • 44. commit <SHA> Author: Victoria Dye <vdye@github.com> Date: Fri Dec 17 10:26:59 2021 -0500 Make error text more helpful Intent
  • 45. commit <SHA> Author: Victoria Dye <vdye@github.com> Date: Fri Dec 17 10:26:59 2021 -0500 Make error text more helpful Intent $ ./git-portable.sh invalid-command Not a valid command: invalid-command $ ./gitportable.sh Not a valid command: $ ./git-portable.sh invalid-command Not a valid command: invalid-command $ ./gitportable.sh Please specify a command What it’s actually doing
  • 46. commit <SHA> Author: Victoria Dye <vdye@github.com> Date: Fri Dec 17 10:26:59 2021 -0500 git-portable.sh: make error text more helpful When provided with incorrect argument, return a message more indicative of the cause of the error. If a user did not provide an argument to ‘git-portable.sh’, the error message returned would be: $ ./git-portable.sh Not a valid command: This does not clearly indicate that the problem is that ‘git-portable.sh’ must be called with a subcommand (e.g., ./git-portable.sh install). To guide the user towards the correct usage, instead print “Please specify a command” when no subcommand is specified. Implementation Intent Context Justification
  • 47. commit <SHA> Author: Victoria Dye <vdye@github.com> Date: Fri Dec 17 10:26:59 2021 -0500 git-portable.sh: make error text more helpful The message “Not a valid command: <invalid command>” is intended to notify the user that their subcommand is invalid. However, when no subcommand is given, the "empty" subcommand results in the same message: "Not a valid command:". This does not clearly guide the user to the correct behavior, so print "Please specify a command" when no subcommand is specified. Implementation Intent Context Justification
  • 48. Recap: guidelines for writing good commits 1. Outline your changes as a narrative structure → Takeway: guides you & your reviewer through changes 2. Break your changes into small, atomic increments → Takeaway: makes review as efficient as possible 3. Use the commit message to explain “what” and “why” → Takeaway: lets readers understand the code how you do
  • 49. But how do I actually do this?
  • 50. git commit --amend git commit --fixup <target> git rebase -i --keep-base <main> git reset <target> Re-committing from scratch? Adjusting what you have?
  • 51. git reset <target> Re-committing from scratch? ● The commits are “undone”. ● Your files don’t change!
  • 52. git commit --amend git commit --fixup <target> git rebase -i --keep-base <main> Adjusting what you have? ● commit --amend - reword and add changes to your latest commit ● commit --fixup - create a commit with a special message that, when rebased, combines with the target (“squashes”) ● rebase -i - reorder, reword, drop, squash, etc. a list of commits
  • 53. git commit --amend git commit --fixup <target> git rebase -i --keep-base <main> git reset <target> Re-committing from scratch? Adjusting what you have?
  • 54. I. Context II. Writing Good Commits III. Performing Commit-by-Commit Reviews IV. Utilizing the Commit History
  • 56. Reviewing commit-by-commit commit <SHA> Author: Victoria Dye <vdye@github.com> Date: Fri Jan 28 10:50:27 2022 -0500 sparse-index: prevent repo root from becoming sparse Prevent the repository root from being collapsed into a sparse directory by treating an empty path as "inside the sparse-checkout". When collapsing a sparse index (e.g. in 'git sparse-checkout reapply'), the root directory typically could not become a sparse directory due to the presence of in-cone root-level files and directories. However, if no such in-cone files or directories were present, there was no explicit check signaling that the "repository root path" (an empty string, in the case of 'convert_to_sparse(...)') was in-cone, and a sparse directory index entry would be created from the repository root directory. The documentation in Documentation/git-sparse-checkout.txt explicitly states that the files in the root directory are expected to be in-cone for a cone-mode sparse-checkout. Collapsing the root into a sparse directory entry violates that assumption, as sparse directory entries are expected to be that the files in the root directory are expected to be in-cone for a cone-mode sparse-checkout. Collapsing the root into a sparse directory entry violates that assumption, as sparse directory entries are expected to be outside the sparse cone and have SKIP_WORKTREE enabled. This invalid state in turn causes issues with commands that interact with the index, e.g. 'git status'. Treating an empty (root) path as in-cone prevents the creation of a root sparse directory in 'convert_to_sparse(...)'. Because the repository root is otherwise never compared with sparse patterns (in both cone-mode and non-cone sparse-checkouts), the new check does not cause additional changes to how sparse patterns are applied. Intent Implementation Context Justification
  • 57. Reviewing commit-by-commit Implementation Prevent the repository root from being collapsed into a sparse directory by treating an empty path as "inside the sparse-checkout". diff --git a/dir.c b/dir.c index d91295f2bc..a136377eb4 100644 --- a/dir.c +++ b/dir.c @@ -1463,10 +1463,11 @@ static int path_in_sparse_checkout_1(const char *path, const char *end, *slash; /* - * We default to accepting a path if there are no patterns or - * they are of the wrong type. + * We default to accepting a path if the path is empty, there are no + * patterns, or the patterns are of the wrong type. */ - if (init_sparse_checkout_patterns(istate) || + if (!*path || + init_sparse_checkout_patterns(istate) || (require_cone_mode && !istate->sparse_checkout_patterns->use_cone_patterns)) return 1;
  • 58. I. Context II. Writing Good Commits III. Performing Commit-by-Commit Reviews IV. Utilizing the Commit History
  • 59. git bisect Narrow down the source of a bug to a specific commit Last good deployment Failed deployment The bug git bisect start <bad> <good>
  • 66. 🎉 Found the bug! 🎉 …but why did it happen in the first place?
  • 67. git blame Find out which commit last changed a line of code Search commits by file, change location, and/or message git log $ git blame -s my-file.py abd52642da46 my-file.py 1) import os 603ab927a0dd oldname.py 3) import re 603ab927a0dd oldname.py 4) 603ab927a0dd oldname.py 5) print(“Hello world”) abd52642da46 my-file.py 5) print(os.stat(“README”)) ... $ git log --oneline -- my-file.py abd52642da46 my-file.py: add README stat printout 7392d7dbb9ae my-file.py: rename from oldname.py 603ab927a0dd oldname.py: create printout script ... $ git log --oneline 09823ba09de1 README.md: update maintainer contact abd52642da46 my-file.py: add README stat printout 7392d7dbb9ae my-file.py: rename from oldname.py 5ad823d1bc48 test.py: commonize test setup 603ab927a0dd oldname.py: create printout script ...
  • 68. I. 🎉 Context 🎉 II. ✨ Writing Good Commits ✨ III. 🎊 Performing Commit-by-Commit Reviews 🎊 IV. 🥳 Utilizing the Commit History 🥳
  • 69. Remember these things! Git commits contextualize your code for a broader audience. You can improve the quality of your commits today by organizing a narrative, making changes small & atomic, and explaining “what” & “why”. Spending time on writing high-quality commits is helpful for anyone and everyone involved in your open- or closed-source project.
  • 70. Questions? Download these slides: https://vdye.github.io/2022/OS101-Writing-Commits.pdf