Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,68 @@
# git-training

## Commit often

It is good practice to commit often to avoid losing work due to e.g. accidentally discarding changes. It's also easier to separate renaming/refactoring work from logic changes if everything is in separate commits. However, this might lead to an incoherent story in the PR commit history. Here we will discuss a couple of methods on how to fix history before creating a PR.

## Amend commits

Sometimes you forgot to stage something before you commit or maybe you notice a small but in your previous commit. In these cases the easiest wayt to keep your history clean is just to add to the previous commit.

```
git add .
git commit --amend
```

Use the following to also fix the commit message:

```
git commit --amend -m "Fixed message"
```

## Cherry picking

Story: You fix something that needs to be fixed both on your local branch to enable further development but then you realise that the same fix needs to be enabled for other developers immediately, before your feature is ready. In the following example we will add some crucial documentation without which no one can continue.

1. `git checkout bikes-and-stuff`
1. `git log`
1. Copy the commit hash of the "Add documentation" commit
1. `git checkout main`
1. `git checkout -b documentation`
1. `git cherry-pick <commit-hash>`

## Interactive rebase

Story: After almost a full day of working, you notice that the feature set you were working on is not ready yet and the scope of your upcoming PR is gradually creeping. Instead of delivering the new 'bikes' feature with a bike editor and documentation all in the same PR, you decide to split the work into first implementing the bikes listing feature and documentation and then continuing with the bike editor later.

1. `git checkout bikes-and-stuff`
1. `git checkout -b bikes`
1. `git rebase --interactive` [bikes onto] `main`
1. Use your favourite editor to reworder the commits

```
pick 37ba009 Add bikes api
pick bfa0c88 Add bikes to the UI
pick 98f84b5 Add bike api
pick 654b5b2 Add status to bikes in ui
pick d9f356e Fix bike status displaying in the ui
pick 93207fc Add documentation
pick a0e4028 Fix: Add missing bike endpoint handler
pick 470aaee Fix handler types
```

nano help (Ctrl+K: Cut, Ctrl+U: Paste, Ctrl+O: Save, Ctrl+X: Exit)

```
pick 37ba009 Add bikes api
squash 470aaee Fix handler types
pick bfa0c88 Add bikes to the UI
drop 98f84b5 Add bike api
pick 654b5b2 Add status to bikes in ui
squash d9f356e Fix bike status displaying in the ui
drop 93207fc Add documentation
drop a0e4028 Fix: Add missing bike endpoint handler
```

5. Manually fix conflicts in editor (or use GUI).
6. `git add .`
7. `git rebase --continue`
25 changes: 25 additions & 0 deletions api/src/bikes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
enum BikeStatus {
Sold,
Stolen,
PartiallyStolen,
NotYetStolen,
NotYetBought,
}

const bikes = [
{ id: "a", brand: "Rose", status: BikeStatus.Sold },
{ id: "b", brand: "Canyon", status: BikeStatus.Sold },
{ id: "c", brand: "Focus", status: BikeStatus.Stolen },
{ id: "d", brand: "Focus", status: BikeStatus.PartiallyStolen },
{ id: "e", brand: "Trek", status: BikeStatus.NotYetBought },
];

const getBike = (id: string) => {
return bikes.find((bike) => bike.id === id);
};

const getBikes = () => {
return bikes;
};

export { getBike, getBikes };
5 changes: 5 additions & 0 deletions api/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
// This file contains the api

import { getBike, getBikes } from "./bikes";

const api = () => {
const handlers: Function[] = [];
handlers.push(getBike, getBikes);

console.log("The api is running...");
};

Expand Down
39 changes: 39 additions & 0 deletions web/src/bikes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from "react";

enum BikeStatus {
Sold,
Stolen,
PartiallyStolen,
NotYetStolen,
NotYetBought,
}

type Bike = {
id: string;
brand: string;
status: BikeStatus;
};

const bikeStatusToDisplayValueMap: Record<BikeStatus, string> = {
[BikeStatus.Sold]: "Sold",
[BikeStatus.Stolen]: "Stolen",
[BikeStatus.PartiallyStolen]: "PartiallyStolen",
[BikeStatus.NotYetStolen]: "NotYetStolen",
[BikeStatus.NotYetBought]: "NotYetBought",
};

const Bikes: React.FC = () => {
const bikes: Bike[] = []; // Get bikes from api

return (
<ul>
{bikes.map((bike) => (
<li>
{bike.brand} | {bikeStatusToDisplayValueMap[bike.status]}
</li>
))}
</ul>
);
};

export { Bikes };
10 changes: 8 additions & 2 deletions web/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import React from 'react'
import React from "react";
import { Bikes } from "./bikes";

const App: React.FC = () => (<>The app</>)
const App: React.FC = () => (
<>
<p>My bikes:</p>
<Bikes />
</>
);