使用 Git 工作流管理多分支的工作

我在项目中使用 Git 作为版本控制工具,并且经常遵循以下策略。 这个策略受到了A successful Git branching model的启发。 我有两个永久分支:master和develop。 以下是我日常开发中遵循的规则: 当我接手一个新任务或决定加入一个功能时,有两条主要路径: 如果功能较为简单,或后续提交不会破坏代码(至少我希望如此):我可以在develop分支上提交,或者创建一个快速功能分支,然后将其合并到develop分支上。 如果功能需要进行多次提交才能完成,可能需要花费几天时间提交才能使功能恢复稳定的状态:我会创建一个功能分支,然后将其合并到develop分支上。 如果我们的生产服务器需要立即采取措施,比如需要尽快解决的 bug 修复,我会创建一个短期修复分支,解决问题后在本地和测试机上进行测试,然后将其合并到 master 和 develop 分支上。 如果我需要在生产服务器上快速推送一个功能或修改,并且 develop 分支中代码不稳定,我希望尽快得到该功能或修改:我可以跳过 develop 分支,创建一个快速功能分支并将其合并到 master 和 develop 分支上,只要这个功能或修改是快速且简单的。如果在后续过程中发现这是一个更复杂的问题,最好等待并稳定 develop 分支上的代码。 develop 分支会一直处于不稳定状态,所以在准备发布时,需要将其放入“冻结”状态。代码经过测试,所有工作流程都经过验证,准备将其合并到 master 分支上。 每次将 develop 或其他短期修复分支合并到 master 分支时,我都会使用版本号做标签,这样如果出现问题可以轻松回滚到先前的状态。

使用 Go 可視化您的本地 Git 貢獻

使用 Go 撰寫 Git 統計分析 CLI 工具的教程 幾年前,我使用 Electron + Meteor.js + gitlog 桌面應用程式掃描了我的本地 Git 存儲庫,並為我提供了一個漂亮的貢獻圖,就像 GitHub.com 上顯示的那樣: 那是在每個應用程序都使用 Electron 之前,由於生成的應用程序大小,我非常不喜歡這種方法,如果與基於 WebKit 的 MacGap 相比較,它的大小要大 50 倍。不管怎樣,它看起來像這樣,具有類似 GitHub 的用戶界面: 我發現它很有用,因為不是所有的項目都在 GitHub 上,一些項目位於 BitBucket 或 GitLab 上,但我所工作的所有代碼都在我的筆記本電腦上,所以這便是“事實的單一來源”。 該應用程序仍在運行,但尚未釋放給大眾使用。 今天我決定將其作為 Go 控制台命令進行移植,因為我仍認為這個概念很好。 本文中要建立的內容 🎉 一個類似下圖的CLI命令,生成類似的圖表 在哪裡可以找到這段程式碼 該程式碼在此 Gist 鏈接上: https://gist.github.com/flaviocopes/bf2f982ee8f2ae3f455b06c7b2b03695 首先的步驟 我將任務分為兩部分: 1.獲取要掃描的文件夾列表 2.生成統計信息 我將使用 Go 命令行標記解析 來讓一個單一命令執行這兩個任務。當傳遞 -add 標記時,該命令將添加新的文件夾到列表中。在沒有標記的情況下執行該命令將生成圖表。為了避免一次性為用戶輸出過多數據,我將限制數據集的時間範圍在過去的 6 個月內。 讓我們為此分層概念撰寫一個簡單的外殼: package main import ( "flag" ) // scan given a path crawls it and its subfolders // searching for Git repositories func scan(path string) { print("scan") } // stats generates a nice graph of your Git contributions func stats(email string) { print("stats") } func main() { var folder string var email string flag....

使用 Laravel Breeze 設置身份驗證

本教程是 Laravel 手冊的一部分,可以從 https://flaviocopes.com/access/ 下載 我們不希望隨機的人進入網站並編輯數據。 我們希望人們先登錄。 如果未登錄,他們會看到狗的列表。 如果已登錄,他們將有能力編輯列表。 Laravel 在框架中為我們提供了內置的身份驗證支持。 為了更加方便,它提供了 Breeze,這是一個應用程序的開始套件工具,可以快速創建我們所需的東西。Breeze 可以快速搭建用戶註冊、登錄、密碼重置、個人資料頁面、儀表板等等功能。它太棒了。對於更高級的需求,我們還有 JetStream,但是 Breeze 更容易設置。 首先,創建一個新的 Laravel 項目,這樣我們可以從一個空白的起點開始。 第一個項目被命名為 first,為了延續傳統,我們將這個第二個項目命名為 second: composer create-project laravel/laravel second 進入該文件夾: cd second 使用 composer 安裝 Breeze: composer require laravel/breeze --dev 現在運行下面的命令: php artisan breeze:install 然後選擇選項 0,即“blade”,並選擇其他問題的默認選項,任務腳本會自動生成遠足點的登錄系統: 現在你可以運行 php artisan serve,並打開 http://127.0.0.1:8000/。 你會看到“Log in”和“Register”鏈接: 所有的登錄功能已經可以正常使用: Laravel 添加了大量的資源來實現這一點。 對於開發者來說,這可能需要花數日的時間,而且這些代碼經過了實戰考驗,你不希望自己寫這些代碼,因為這是一個非常重要且需要進行良好的安全性測試的功能。 我建議你查看文件結構,並將其與第一個項目進行對比。許多新東西已經被添加了,例如視圖: 但在進一步之前,我們需要為此項目設置數據庫,就像我們在第一個項目中所做的那樣。我們打開 .env 文件,註釋掉以下幾行: 然後添加以下內容: DB\_CONNECTION=sqlite 以配置 SQLite 數據庫。 然後運行下面的命令: php artisan migrate 在另一個終端窗口中,運行 npm install 命令,然後運行 npm run dev 命令,這是一個長時間運行的過程,需要與 php artisan serve 一起運行(⚠️ 請確保在 second 文件夾中運行,而非 first 項目中運行,我剛剛花了15分鐘的時間才找到問題所在)。...

使用 macOS Shortcuts 轉換圖像或調整大小

長久以來,我一直使用 Automator 腳本將圖像轉換為 JPG 格式。 這是我經常做的事情,因為在某些情況下,PNG 圖像和 JPG 圖像的差異是巨大的,這取決於圖像本身。 有時將圖像轉換為 JPG 可以使文件大小減少 5 倍。對於大圖像來說,這是值得一試的。 (由於透明背景,PNG 更好看,但是在文件大小和美觀之間有一個平衡) macOS Monterey 是最新的 macOS 版本,它附帶了一個未來可能取代 Automator 的工具,我認為這個工具在 iOS 和 iPadOS 平台上已經有一段時間了:Shortcuts。 我從未在這些平台上使用過這個應用程序,因為我從來沒有需要做任何花俏的事情。 但是自從換了一台新的 Mac 之後,我決定重做我的一些小自動化。我沒有很多。我只有這個可以將任何圖像轉換為 JPG 的自動化,還有另一個可以將圖像調整為 1200px 的自動化。 在這篇文章中,我想描述一下如何完成第一個自動化。 打開 Shortcuts: 點擊 + 按鈕,或從選單中選擇 文件 -> 新建快捷方式。 現在在右側,您可以選擇一個操作。搜索“finder”,並選擇“獲取 Finder 中選定的文件”操作: 將其拖到屏幕左側: 現在選擇“轉換圖像”: 在右側的設置選項卡中,您可以選擇將此快捷方式用作 Finder 中的“快速操作”,這樣您就可以右鍵單擊圖像,然後選擇將其轉換為 JPG: 請確保只設置接收圖像,取消選擇第一個操作中的所有其他文件類型: 最後,添加一個“移動文件”操作,將轉換後的文件保存到桌面: 不幸的是,我找不到一種方法將 JPG 檔案保存到當前文件夾並替換所選擇的文件。我想如果花更多時間,我可以解決這個問題,如果您知道如何做到這一點,請在 Twitter 上聯繫我 @flaviocopes 🙃 但這不是什麼大問題,我可以接受這樣。如果我覺得這個過程太繁瑣,我總可以在 Automator 中重新製作工作流程。但至少我現在知道如何使用 Shortcuts。 這是將圖像調整為 1200px 的快捷方式:

使用 map、filter、reduce 和 find 编写 JavaScript 循环

如何在 JavaScript 中执行常见的操作,其中可能使用循环,使用 map()、filter()、reduce() 和 find() 循环通常用于在任何编程语言中对数组执行操作:给定一个数组,您可以迭代其元素并执行计算。 让我们看看如何选择常见需求并使用**函数式编程**方法执行它们,而不使用循环。 注意:我不推荐其中一种方法。我只是想介绍执行相同操作的不同方式,并可能向您介绍一些以前可能从未使用过的新函数。 map、filter、reduce、find 这些是三个非常强大的数组函数: map 返回一个与原始数组具有相同长度的数组。 filter 如其名所示,返回比原始数组少的项目的数组。 reduce 返回一个单个值(或对象)。 find 返回数组中满足条件的第一个项目。 map、filter 和 reduce 在 ES5 中引入,因此您可以安全地在每个浏览器中使用它们的实现已经多年了。 find 在 ES6/ES2015 中引入。 它们提供了一种更加声明性的方法,而不是命令性的方法(描述应该发生的情况,而不是写出应该发生的每个微小处理)。 使用 map 在每个元素上执行某些操作 使用循环的示例如下: const performSomething = (item) => { // ... return item; }; const items = ['a', 'b', 'c']; items.forEach((item) => { performSomething(item); }); 使用声明性方法,您告诉 JavaScript 在每个元素上执行某些操作: const items = ['a', 'b', 'c']; const newArray = items.map((item) => performSomething(item)); 这将生成一个新数组,而不是编辑原始数组(我们称之为不可变性)。...

使用 MySQL 和 Node 的基礎操作

MySQL 是世界上最受歡迎的關聯式資料庫之一。了解如何在 Node.js 中使用它。 MySQL 是世界上最受歡迎的關聯式資料庫之一。 當然,Node 生態系統中有幾個不同的套件可以讓您與 MySQL 進行互動,存儲數據,檢索數據等等。 我們將使用 mysqljs/mysql,這個套件在 GitHub 上有超過 12,000 顆星並且存在多年。 安裝 Node mysql 套件 用以下指令安裝: npm install mysql 初始化數據庫連接 首先要引入套件: const mysql = require('mysql') 然後創建一個連接: const options = { user: 'the_mysql_user_name', password: 'the_mysql_user_password', database: 'the_mysql_database_name' } const connection = mysql.createConnection(options) 通過調用以下代碼來建立新的連接: connection.connect(err => { if (err) { console.error('An error occurred while connecting to the DB') throw err } }) 連接選項 在上面的例子中,options 對象包含了 3 個選項:...

使用 Next.js Router 偵測當前鏈接

在 Next.js 中如何使用 Router 偵測當前鏈接並給予其一個類別,以便我們可以使用 CSS 來為其設置樣式。 當與鏈接一起工作時,一個非常重要的功能就是確定當前 URL,特別是為活動鏈接指定一個類別,以便我們可以將其與其他鏈接區分開來並進行不同的樣式設定。 這在網站的標頭中特別有用。 Next.js 預設的 Link 組件(next/link)並不會自動為我們完成這個功能。 我們可以使用兩種技術。一種是將邏輯添加到 Link 的子組件中。另一種技術是在另一個我們可以構建的組件中使用 Link 來處理此邏輯。 讓我們從最簡單的方法開始: import React from 'react' import Link from 'next/link' import { useRouter } from 'next/router' const menu = [ { title: '首頁', path: '/home' }, { title: '探索', path: '/explore' }, { title: '通知', path: '/notifications' }, ] const Sidebar = () => { const router = useRouter() return ( <div> {menu....

使用 Node 寫入檔案

如何使用 Node.js 寫入檔案 在 Node.js 中,最簡單的方法是使用 fs.writeFile() API 來寫入檔案。 範例: const fs = require('fs') const content = '一些內容!' fs.writeFile('/Users/flavio/test.txt', content, (err) => { if (err) { console.error(err) return } // 檔案已成功寫入 }) 或者,你可以使用同步版本的 fs.writeFileSync(): const fs = require('fs') const content = '一些內容!' try { const data = fs.writeFileSync('/Users/flavio/test.txt', content) // 檔案已成功寫入 } catch (err) { console.error(err) } 預設情況下,如果該文件已存在,該 API 將替換該文件的內容。 你可以通過指定標誌 (flag) 改變預設行為: fs.writeFile('/Users/flavio/test.txt', content, { flag: 'a+' }, (err) => {}) 你可能會使用的標誌 (flags) 有:...

使用 Node 獲取 HTTP 請求的請求體數據

了解如何使用 Node 通過 HTTP 請求體提取發送的 JSON 數據。 這是如何提取請求體中作為 JSON 發送的數據。 如果你使用的是 Express,那就非常簡單:使用 body-parser Node 模塊。 例如,要獲取此請求的請求體: const axios = require('axios') axios.post('/todos', { todo: '購買牛奶', }) 這是對應的服務器端代碼: const bodyParser = require('body-parser') app.use( bodyParser.urlencoded({ extended: true, }) ) app.use(bodyParser.json()) app.post('/endpoint', (req, res) => { console.log(req.body.todo) }) 如果你沒有使用 Express,而是想在原生的 Node 中實現這個功能,當然需要更多的工作,因為 Express 為你抽象了很多內容。 關鍵的是,當你使用 http.createServer() 初始化 HTTP 服務器時,回調函數被調用時,服務器已經獲取了所有的 HTTP 標頭,但是沒有請求體。 在連接的回調中,傳遞的 request 對象是一個流。 因此,我們需要監聽請求體內容被處理的事件,並且它以塊的形式進行處理。 我們首先通過監聽流的 data 事件來獲取數據,在數據結束時,流的 end 事件被調用一次: const server = http.createServer((req, res) => { // 我們可以訪問 HTTP 標頭 req....

使用 Node 讀取文件

如何使用 Node 和 fs 模組來讀取文件 在 Node 中,最簡單的讀取文件的方式是使用 fs.readFile() 方法,將文件路徑和一個回調函數作為參數傳遞給該方法,回調函數將在文件數據(以及錯誤)讀取完成後被調用: const fs = require('fs') fs.readFile('/Users/flavio/test.txt', (err, data) => { if (err) { console.error(err) return } console.log(data) }) 另外,你也可以使用同步版本的 fs.readFileSync(): const fs = require('fs') try { const data = fs.readFileSync('/Users/flavio/test.txt', 'utf8') console.log(data) } catch (err) { console.error(err) } 默認的編碼格式是 utf8,但你也可以通過第二個參數來指定自定義的編碼。 fs.readFile() 和 fs.readFileSync() 這兩個方法在返回數據之前將完整的文件內容讀取到內存中。 這意味著,處理大文件將對內存消耗和程序執行速度產生較大的影響。 在這種情況下,更好的選擇是使用流(stream)來讀取文件內容。