Best Practices for Git

Commits, what to do and what to Avoid

Diogo Sampaio • July 19, 2024

The article "Good Commit ✔ VS. Bad Commit ❌: Best Practices for Git" discusses the differences between good and bad commits in Git, an essential version control system for developers. A good commit is characterized by clear and concise messages explaining what was changed and why, in addition to being atomic, meaning they focus on a single logical change. Examples include "Fix bug in authentication module" or "Add tests for login function."

good commit example: git commit -m

On the other hand, bad commits have vague messages like "Various updates" and combine multiple unrelated changes, making it harder to trace bugs and review code.

bad commit example: git commit -m

In my opinion, following good practices not only improves collaboration within teams but also facilitates long-term project maintenance. Clarity in commit messages can be seen as an investment in the future of the project, saving time and effort when changes need to be revisited.

Global CrowdStrike Failure: Lessons Learned

The Pragmatic Engineer article details a critical incident caused by CrowdStrike, a cybersecurity company, that led to the crash of millions of Windows machines worldwide. This incident started when CrowdStrike pushed a content update to all its clients.

Incident Details

  • The Process That Caused the Crash: The process responsible for the bug is called "CSAgent.sys." This process was instructed to move bytes from the Assembly instruction "mov r9d, [r8]," where r8 was an unmapped (invalid) address, resulting in the operating system crashing.
  • Problematic Content File: The crash was caused by reading a new content file that CrowdStrike sent to all customers, called "C-00000291-*.sys." There was an issue with how this file was parsed, resulting in a logic error that caused the system to crash.
  • Purpose of the Update: The update aimed to detect malicious named pipes. CrowdStrike's Falcon product monitors how processes communicate on a machine or across the network to identify malicious activity. The update added a new rules file to filter suspicious named pipes. Named pipes are a common concept in operating systems for inter-process communication.
  • Unhandled Error: The configuration update triggered a logic error that caused the operating system to crash. CrowdStrike disclosed that the issue was not related to null bytes in the Channel 291 file or any other Channel file.

Problem Analysis

The core problem was an Assembly instruction that attempted to move an invalid memory location, leading to the crash of Windows devices. This incident highlights the complexity and interdependence of modern systems, where a small change can have significant global repercussions.

In my view, this incident serves as a warning about the importance of robust change management practices and validation of updates before release. The failure underscores the need for resilience and redundancy in systems, along with clear and efficient communication during crises. Companies should use these events as case studies to improve their infrastructure and incident response procedures. Implementing rigorous testing and contingency plans can make the difference between a quick recovery and a prolonged disaster.

A Single Line of Code: Massive Impact

Ariane 5 Disaster

On June 4, 1996, the ESA launched the Ariane 5, which disintegrated 37 seconds after launch due to a software failure in the guidance system. The problem was an overflow of value resulting from the improper conversion of a 64-bit floating-point value to a 16-bit integer. This error, a remnant from the Ariane 4 code, combined with the steeper trajectory of the Ariane 5, resulted in the destruction of the rocket and the loss of cargo valued at nearly half a billion euros.

SQLException Incident That Grounded an Airline

A recent incident grounded flights across the U.S. due to a synchronization error between the primary and backup databases. Contractors "accidentally deleted files," resulting in a nationwide outage that affected over 11,000 flights. This event mirrors a problem described in Michael Nygard's book "Release It," where an uncaught SQL exception caused resource pool exhaustion, paralyzing an airline's central system for three hours.

Boeing 737 MAX Disaster

In 2018 and 2019, two Boeing 737 MAX planes crashed, killing 346 people. The problem was with the MCAS system, which relied on data from only one angle-of-attack sensor. Incorrect data caused the system to activate unnecessarily, causing the plane's nose to pitch down repeatedly. Inadequate information for pilots and outsourcing of software development contributed to the accidents.

Lessons Learned

These cases highlight the importance of rigor in software development, especially in critical systems. It is essential to avoid copying code without fully understanding it, implement proper exception handling, consider user requirements, and perform comprehensive testing. In the case of Ariane 5, the lack of testing and improper use of legacy code led to a catastrophic failure. The airline incident highlighted the importance of proper exception handling and resource management. The Boeing 737 MAX disaster emphasized the risks of relying on a single point of failure and inadequate communication with end-users.

Recommendations

  • Avoid Copying Code Without Understanding: Using code uncritically can introduce hidden flaws.
  • Importance of Handling Exceptions: Programming errors must be handled properly to prevent catastrophic failures.
  • Attention to Requirements: Changes in requirements, such as the rocket's trajectory, must be carefully considered.
  • Comprehensive Testing: Testing software under real and simulated conditions is essential to ensure its robustness.
  • Redundancy: Remove single points of failure to increase system resilience.
  • Simplification: Keep systems simple to avoid introducing new vulnerabilities.

These incidents serve as reminders of the risks involved and the responsibility that falls on software professionals. Implementing robust testing practices, exception handling, and deep understanding of the code used are essential to prevent future disasters.

ORMs: Just Learn SQL

The author of the article "What ORMs Have Taught Me: Just Learn SQL" concludes that ORMs (Object-Relational Mappers) can be more harmful than helpful. While they can complement SQL in a program, they should not replace it. After working with Postgres and SQLite, primarily using SQLAlchemy and Hibernate, the author faced several inherent issues with ORMs, such as "Object/Relational Impedance Mismatch," entity identity, dual schemas, and partial objects.

Problems with ORMs begin with "attribute creep" and excessive use of foreign keys, resulting in extremely wide tables and inefficient queries. Queries that start simple, like query(Foo.class).add(Restriction.eq("x", value)), become complicated as attributes increase. An example given is the query that initially works well with five attributes but becomes a "data fire hose" when the table has hundreds of attributes, similar to using SELECT * in SQL. For simple models, ORMs may work well, but when it comes to complex joins or window functions, ORMs can hinder the generation of efficient SQL. Often, the solution is to write SQL queries directly using a template system, keeping the table descriptions in the ORM.

Maintaining data definitions both in the application and in the database is redundant and problematic. The author prefers to keep definitions in the database and use them in the application. This avoids the complexity of synchronizing data definitions between two systems. However, data migration remains a significant problem, as changing the data model in the application is easy, but migrating data in the database is complex and error-prone. Handling entity identities and transactions is complicated with ORMs.

The author describes the difficulty of handling database identifiers and the complexity of managing transactions efficiently. He mentions the need to manipulate the ORM to obtain database identifiers through techniques like manually flushing the cache or partial commits.

Reflecting on his experience, the author questions the widespread rejection of stored procedures and considers the database as a type of data with an API: queries. He concludes that learning SQL is essential, as ORMs, while useful for representing data definitions, are inadequate for writing efficient queries and managing object state. Therefore, for anyone using an RDBMS, learning SQL is indispensable. This approach allows for simpler and more direct integration with the database, avoiding the common problems associated with using ORMs.

In my opinion, the critique of ORMs presented is quite relevant, especially in scenarios where query performance and complexity are crucial. While ORMs offer a convenient abstraction, they often introduce additional complexity and inefficiencies that could be avoided with a good understanding of SQL. I agree that, in many cases, learning SQL and using it directly is a more effective and efficient approach, especially when dealing with complex data models and the need for optimized queries.

Theatre.js: Animation Tool for the Browser

Theatre.js is a JavaScript animation library that provides professional tools for motion design on the web. Highly extensible, it allows for the creation of complex and detailed animations, from cinematic scenes in THREE.js to UI interactions.

With a robust timeline, Theatre.js makes it easy to create and manage animations. It includes a visual editor that allows for adjusting animations directly in the browser, providing precise control over every frame.

Theatre.js documentation is comprehensive, with detailed guides and tutorials to help developers get started quickly. For more information, visit the Theatre.js documentation.

Theatre.js represents a significant advancement in the democratization of animation tools for the web. By bringing advanced animation capabilities to the browser, it facilitates the work of developers and designers, promoting creativity and innovation. The combination of an intuitive visual editor with a powerful timeline makes this library ideal for projects that require detailed and precise animations. Adopting Theatre.js can transform how animations are created and managed on the web, making complex processes more accessible and efficient.

The Uniqueness of Japanese Websites: Cultural and Aesthetic Factors at Play

In the article "Why Japanese Websites Look So Different," Mirijam Missbichler analyzes the peculiarities of Japanese websites and explores the cultural, technological, and aesthetic reasons contributing to their distinctive style. Here are the key points discussed:

Challenges in Font Creation and Front-End Development:

  • Font Complexity: Creating fonts for Japanese is significantly more complex than for alphabet-based languages. While an English font may have around 230 glyphs, a Japanese font must cover between 7,000 and 16,000 glyphs due to the three writing systems and the large number of kanji characters. This technical complexity leads to the frequent use of images with text instead of digital fonts.
  • Design Implications: The difficulty and time required to create new fonts result in a limited number of options, contributing to the use of visually dense and less optimized designs.

Technological Development and Digital Literacy:

  • Outdated Technology: Despite being a global leader in robotics and technology, Japan still uses technologies like floppy disks and fax machines. Japan "has been living in the year 2000 since 1985," reflecting a technological lag that can impact how websites are designed and updated.
  • Digital Literacy: This technological lag may manifest in more conservative and less updated web designs, influencing how sites are developed and maintained.

Cultural Influences:

  • Visual Preferences: Japanese website design is shaped by cultural traditions that favor a rich and detailed aesthetic. Instead of Western minimalism, many Japanese sites feature layouts packed with information and vibrant colors. This reflects a cultural approach that values extensive and detailed presentation.
  • User Experience: In contexts such as online shopping and government information, a greater amount of detail is seen as beneficial, allowing users to make more informed decisions and reduce the risk of errors.

Expectations and Visual Influences:

  • Comparative Examples: The article compares websites like Starbucks in the U.S. and Japan to illustrate the differences. The American site features a clean and modern design with distinct fonts, while the Japanese site uses images to represent text and buttons, resulting in a busier and more complex appearance.
  • Cultural Perception and Adaptation: While Japanese design may seem confusing to Westerners due to its information density, it is adapted to local cultural expectations. The visual complexity is a way of providing information more engagingly and in detail for the Japanese audience.

Opinion:

The design of Japanese websites may seem exaggerated and overloaded to those used to Western minimalism. However, this difference is an adaptation to Japan's cultural and technological norms. The phrase "Japan, living in the year 2000 since 1985" aptly illustrates the technological lag that still influences website design, resulting in visual choices that prioritize detailed information and error prevention. Understanding these cultural and technical nuances is essential to appreciate Japanese design and avoid hasty judgments based solely on Western perspectives.

References

Ahmed, Sheraz. Good Commit vs Bad Commit: Best Practices for Git. Dev.to.

Pragmatic Engineer. The Biggest Ever Global Outage: Lessons. Pragmatic Engineer Newsletter.

Milan. How a Single Line of Code Brought Down a Giant. TechWorld Newsletter.

Wozniak, Steve. What ORMs have taught me: just learn SQL. Wozniak's Blog.

TheatreJS. TheatreJS --- A Framework for Building JavaScript Applications. TheatreJS.

Missbichler, Mirijam. Why Japanese Websites Look So Different. Medium.


Latest related articles