You can use git rev-parse to show the SHA of the current Git commit:| adamj.eu
When working on a feature, you might split it into several stacked branches, so you can merge each one separately. But updating such branches can be annoying since you have to manage them independently. Git 2.38 (2022-10-15) made this management easier with the new --update-refs option, which can rebase a stack of branches at once. Let’s look at a couple of examples.| adamj.eu
Archives for 2019| adamj.eu
Django’s runserver automatically reloads when you change Python files. Without this autoreloading feature, you’d need to manually restart the server every time you made a code change. However, the default autoreloading implementation is inefficient, as it constantly polls the filesystem for changes. The alternative to polling is to …| Adam Johnson
git cherry-pick allows you to copy a commit another branch to your current one. A common use case is copying a bug fix from a long-running feature branch to another one, so that it can be merged sooner, for example:| adamj.eu
To check if a commit SHA exists on a given branch, you have a couple of options. git merge-base--is-ancestor For a low-level query about commit existence, use git merge-base with its --is-ancestor option. This command only returns the result through its exit status, so it’s most useful for …| Adam Johnson
Take this code: importrandomdefd6()->int:try:returnrandom.randint(1,6)exceptException:# Ignore issues in random number generationpassfinally:# Fallback value chosen by a fair dice rollreturn4print("Your random number is:",d6()) Run it on Python 3.14+, and you’ll see …| Adam Johnson
When testing code that outputs to the terminal through either standard out (stdout) or standard error (stderr), you might want to capture that output and make assertions on it. To do so, use contextlib.redirect_stdout() and contextlib.redirect_stderr() to redirect the respective output streams to in-memory buffers that you can …| Adam Johnson
When you want to count the number of files within a Git repository, it's generally best to use Git itself for the task because it will skip over any generated or downloaded files. Here is a command chain to use to count all committed files within the current directory:| adamj.eu
Archives for 2025| adamj.eu
Here’s a little tip based on some work that I did recently. The project has a URL pattern where the first part of the URL matches the current role the user is viewing the site as. Let’s say the roles are “chef”, “gourmand”, and “foodie”—example URLs might …| Adam Johnson
Sometimes, it’s useful to branch the behaviour of your code based on the version of a package that you have installed. This may be to support an upgrade in your project, or for your own package to support different versions of a dependency. Some Python packages provide a top-level …| Adam Johnson
Within Django’s popular admin site, you can override ModelAdmin.get_queryset() to customize the queryset used by the admin views. It’s often used for performance optimizations, such as adding a select_related() call to batch-fetch related objects:| adamj.eu
There you are, minding your own business, rebasing your branch and… surprise! A merge conflict!| adamj.eu
Archives for 2022| adamj.eu
I’ve found it useful, on occasion, to iterate through all registered URL patterns in a Django project. Sometimes this has been for checking URL layouts or auditing which views are registered. In this post, we’ll look at a pattern for doing that, along with an example use case …| Adam Johnson
Typically, we share repositories through a Git host, like GitHub, allowing others to clone the repository to get a copy. But sometimes that’s not an option, for example when trying to get someone started on your project when corporate onboarding processes take days to grant GitHub access.| adamj.eu
You started a new branch, worked hard on initial commits, and you’re ready to send it for review. You try to push and:| adamj.eu
By default, if you mistype a Git command, it will list similar commands that you might have meant:| adamj.eu
On several Django projects I’ve worked on, there has been a requirement for performing database modifications beyond Django migrations. For example:| adamj.eu
You may encounter this warning when cloning a Git repository:| adamj.eu
Git: find the largest commits| adamj.eu
Many Git commands output “advice”, with hints about which commands you could run next. Most notably, git status gives you advice for what to do about files in each state:| adamj.eu
robots.txt is a standard file to communicate to “robot” crawlers, such as Google’s Googlebot, which pages they should not crawl. You serve it on your site at the root URL /robots.txt, for example https://example.com/robots.txt.| adamj.eu
Python: my new uv setup for development| adamj.eu
Archives for 2024| adamj.eu
Django: Introducing Djade, a template formatter| adamj.eu
When we write custom management commands, it’s easy to write integration tests for them with call_command(). This allows us to invoke the management command as it runs under manage.py, and retrieve the return code, standard output, and standard error. It’s great, but has some overhead, making our tests slower than necessary. If we have logic separated out of the command’s handle() method, it improves both readability and testability, as we can unit test it separately.| adamj.eu
argparse, the standard library module that Django uses for parsing command line options, supports sub-commands. These are pretty neat for providing an expansive API without hundreds of individual commands. Here’s an example of using sub-commands in a Django management command:| adamj.eu
Django requires every change to model fields and meta classes to be reflected in database migrations. This applies even to things that don’t typically affect the database, such as Field.choices. When iterating on code, it’s easy to make a model change and forget to update the migrations accordingly. If you don’t have any protection, you might even deploy code that crashes due to out-of-date migrations!| adamj.eu
I have just released an update to my book Boost Your Git DX, six months after its initial release. This update adds some extra content and has a bunch of edits based on reader feedback. The PDF is now ten pages longer, for a total of 363.| adamj.eu
git bisect efficiently searches for a commit responsible for changing a given behaviour. git log lets you see when a given file or line changed, but that’s often insufficient when the cause of some change is unclear. In such cases, git bisect shines, as it lets you check your running system.| adamj.eu
Contrary to common belief, Git doesn’t store diffs. It actually stores snapshots of whole files, heavily compressed to reduce redundancy. Then when displaying a diff is required, git diff generates it on the fly.| adamj.eu
Global Privacy Control (GPC) is a specification for web browsers to signal website operators not to share or sell the user’s data. This signal is intended to exercise legal data privacy rights such as those provided by the California Consumer Privacy Act (CCPA) or the EU’s General Data Protection Regulation (GDPR). While GPC is a proposal, support has been implemented in Firefox and several other privacy-focused browsers and extensions.| adamj.eu