Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 11175] ファイルの概要

このコミットは、Go言語の実験的なSSHパッケージ(exp/ssh)からsrc/pkg/exp/ssh/server_shell_test.goというテストファイルを削除するものです。これは、以前のパッチ適用プロセスにおいて、本来削除されるべきファイルが誤って復元されてしまった問題を修正するためのものです。

コミット

commit a33b76081b1c66eb1c3c171853782de5dcff8456
Author: Adam Langley <agl@golang.org>
Date:   Sun Jan 15 10:08:48 2012 -0500

    exp/ssh: patching in the last change lost that a file was deleted.
    
    R=golang-dev
    CC=golang-dev
    https://golang.org/cl/5541060

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/a33b76081b1c66eb1c3c171853782de5dcff8456

元コミット内容

exp/ssh: patching in the last change lost that a file was deleted.

R=golang-dev
CC=golang-dev
https://golang.org/cl/5541060

変更の背景

このコミットの背景には、Gitにおけるパッチ適用やリベースといった操作の特性が関係しています。コミットメッセージ「patching in the last change lost that a file was deleted.」が示すように、以前の変更("last change")を適用する際に、本来削除されるべきファイル(server_shell_test.go)の削除情報が失われ、そのファイルが誤ってリポジトリに復元されてしまったと考えられます。

このような状況は、例えば以下のような場合に発生し得ます。

  1. 手動でのパッチ適用ミス: git applyなどでパッチを適用する際に、削除を示す行が正しく解釈されなかったり、競合が発生して手動で解決する際に誤って削除を取り消してしまったりするケース。
  2. リベース時の問題: git rebase中に、削除コミットがスキップされたり、競合解決時に削除が無視されたりすることで、ファイルが「復活」してしまうケース。
  3. ツールやスクリプトの不具合: 自動化されたスクリプトやツールがGit操作を行う際に、ファイル削除のメタデータを正しく扱えなかった場合。

このコミットは、その誤って復元されたserver_shell_test.goファイルを再度削除することで、リポジトリの状態を正しい(意図された)状態に戻すための修正措置です。

前提知識の解説

Go言語のexpパッケージ

Go言語の標準ライブラリには、exp(experimental、実験的)というプレフィックスを持つパッケージ群が存在します。これらは、Goチームによって開発・メンテナンスされていますが、まだAPIの安定性が保証されておらず、将来的に変更される可能性があるパッケージです。しかし、その中には将来的に標準ライブラリに取り込まれる可能性のある重要な機能が含まれていることもあります。exp/sshは、Go言語でSSH(Secure Shell)プロトコルを扱うための実験的な実装でした。現在では、golang.org/x/crypto/sshとして独立したモジュールとして提供されており、Goの公式なSSH実装となっています。

Gitのパッチ適用とリベース

  • パッチ適用: Gitでは、git diffで生成された差分情報(パッチファイル)をgit applygit amコマンドで他のリポジトリに適用することができます。これにより、あるコミットの変更内容を別のブランチやリポジトリに持ち込むことが可能です。
  • リベース: git rebaseは、一連のコミットを別のベースコミットの上に再適用する操作です。これにより、コミット履歴を線形に保ち、マージコミットを減らすことができます。

これらの操作は強力ですが、特にファイル削除を含む変更を扱う際には注意が必要です。パッチファイルが破損していたり、リベース中に競合が発生して手動で解決する際に誤った操作を行うと、本来削除されるべきファイルが残ってしまったり、逆に残すべきファイルが削除されてしまったりする可能性があります。

Gerrit

Gerritは、Goプロジェクトを含む多くのオープンソースプロジェクトで利用されているWebベースのコードレビューおよびプロジェクト管理ツールです。Gitリポジトリと連携し、開発者が変更をプッシュする前にコードレビューを強制することで、コード品質の向上と一貫性の維持に貢献します。golang.org/cl/で始まるリンクは、Gerrit上の特定の変更セット(Change-ID)を指します。Goプロジェクトでは、コミットメッセージにGerritのChange-IDを含めることが一般的です。

技術的詳細

このコミットの技術的な詳細は、src/pkg/exp/ssh/server_shell_test.goファイルの完全な削除に集約されます。

  • ファイルの役割: server_shell_test.goは、exp/sshパッケージ内のSSHサーバーシェル機能に関するテストコードを含んでいました。具体的には、MockChannelというモックオブジェクトを使用してSSHチャネルの振る舞いをシミュレートし、NewServerShellで作成されたシェルがReadLineなどの操作を正しく処理するかどうかを検証していました。TestClose関数やTestKeyPresses関数が含まれており、それぞれチャネルのクローズ処理やキー入力の処理をテストしていました。
  • 削除の意図: コミットメッセージから、このファイルの削除は意図されたものであり、以前の変更で誤って復元されてしまった状態を修正するための「再削除」であることが明確です。なぜこのテストファイルが最初に削除されたのか(例えば、テストの再編成、機能の廃止、より包括的なテストへの統合など)は、このコミット単体からは判断できませんが、このコミットはあくまでその「削除」という意図を再確立するものです。
  • 影響: このファイルの削除により、exp/sshパッケージのテストスイートからserver_shell_test.goに含まれていたテストケースが完全に除去されます。これは、当該テストがもはや必要ない、あるいは別の場所でカバーされていることを意味します。

コアとなるコードの変更箇所

このコミットにおけるコアとなるコードの変更は、src/pkg/exp/ssh/server_shell_test.goファイルの完全な削除です。Gitの差分表示では、ファイルが削除された場合、そのファイルの内容がすべて削除されたものとして表示されます。

diff --git a/src/pkg/exp/ssh/server_shell_test.go b/src/pkg/exp/ssh/server_shell_test.go
deleted file mode 100644
index aa69ef7fed..0000000000
--- a/src/pkg/exp/ssh/server_shell_test.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ssh
-
-import (
--	"io"
--	"testing"
-)
-
-type MockChannel struct {
--	toSend       []byte
--	bytesPerRead int
--	received     []byte
-}
-
-func (c *MockChannel) Accept() error {
--	return nil
-}
-
-func (c *MockChannel) Reject(RejectionReason, string) error {
--	return nil
-}
-
-func (c *MockChannel) Read(data []byte) (n int, err error) {
--	n = len(data)
--	if n == 0 {
--		return
--	}
--	if n > len(c.toSend) {
--		n = len(c.toSend)
--	}
--	if n == 0 {
--		return 0, io.EOF
--	}
--	if c.bytesPerRead > 0 && n > c.bytesPerRead {
--		n = c.bytesPerRead
--	}
--	copy(data, c.toSend[:n])
--	c.toSend = c.toSend[n:]
--	return
-}
-
-func (c *MockChannel) Write(data []byte) (n int, err error) {
--	c.received = append(c.received, data...)
--	return len(data), nil
-}
-
-func (c *MockChannel) Close() error {
--	return nil
-}
-
-func (c *MockChannel) AckRequest(ok bool) error {
--	return nil
-}
-
-func (c *MockChannel) ChannelType() string {
--	return ""
-}
-
-func (c *MockChannel) ExtraData() []byte {
--	return nil
-}
-
-func TestClose(t *testing.T) {
--	c := &MockChannel{}
--	ss := NewServerShell(c, "> ")
--	line, err := ss.ReadLine()
--	if line != "" {
--		t.Errorf("Expected empty line but got: %s", line)
--	}
--	if err != io.EOF {
--		t.Errorf("Error should have been EOF but got: %s", err)
--	}
-}
-
-var keyPressTests = []struct {
--	in   string
--	line string
--	err  error
-}{
--	{
--		"",
--		"",
--		io.EOF,
--	},
--	{
--		"\\r",
--		"",
--		nil,
--	},
--	{
--		"foo\\r",
--		"foo",
--		nil,
--	},
--	{
--		"a\\x1b[Cb\\r", // right
--		"ab",
--		nil,
--	},
--	{
--		"a\\x1b[Db\\r", // left
--		"ba",
--		nil,
--	},
--	{
--		"a\\177b\\r", // backspace
--		"b",
--		nil,
--	},
-}
-
-func TestKeyPresses(t *testing.T) {
--	for i, test := range keyPressTests {
--		for j := 0; j < len(test.in); j++ {
--			c := &MockChannel{
--				toSend:       []byte(test.in),
--				bytesPerRead: j,
--			}
--			ss := NewServerShell(c, "> ")
--			line, err := ss.ReadLine()
--			if line != test.line {
--				t.Errorf("Line resulting from test %d (%d bytes per read) was '%s', expected '%s'", i, j, line, test.line)
--				break
--			}
--			if err != test.err {
--				t.Errorf("Error resulting from test %d (%d bytes per read) was '%v', expected '%v'", i, j, err, test.err)
--				break
--			}
--		}
--	}
-}

コアとなるコードの解説

上記の差分は、src/pkg/exp/ssh/server_shell_test.goファイルが完全に削除されたことを示しています。

  • deleted file mode 100644: この行は、ファイルが削除されたことを示し、元のファイルのパーミッションモードが100644(通常のファイル)であったことを示しています。
  • index aa69ef7fed..0000000000: これは、ファイルのGitオブジェクトIDがaa69ef7fedから0000000000(nullオブジェクトID、つまりファイルが存在しない状態)に変わったことを示しています。
  • --- a/src/pkg/exp/ssh/server_shell_test.go+++ /dev/null: 差分のヘッダーで、左側(a/)が変更前のファイル、右側(b/)が変更後のファイルを示します。b//dev/nullであることは、ファイルが削除されたことを意味します。
  • @@ -1,134 +0,0 @@: これはハンクヘッダーで、変更前のファイルが1行目から134行目まで存在し、変更後のファイルには0行が存在することを示しています。
  • 続くすべての行が-で始まるのは、これらの行がすべて削除されたことを意味します。

この変更は、特定の機能追加やバグ修正のためのコード変更ではなく、リポジトリの整合性を保つためのクリーンアップ作業です。これにより、意図しないファイルがリポジトリに残存することを防ぎ、プロジェクトの健全性を維持します。

関連リンク

  • GitHub上のコミットページ: https://github.com/golang/go/commit/a33b76081b1c66eb1c3c171853782de5dcff8456
  • Gerrit Change-ID: https://golang.org/cl/5541060
    • このリンクはGoプロジェクトのGerritシステムにおける変更セット(Change-ID)を指します。コミットが2012年のものであるため、現在のGerritシステムで直接このChange-IDに対応する内容が見つからない可能性があります。これは、Gerritのシステム変更や古いChange-IDのアーカイブ化によるものです。

参考にした情報源リンク

  • Go言語のx/crypto/sshパッケージに関する情報: https://pkg.go.dev/golang.org/x/crypto/ssh
    • exp/sshパッケージの現在の後継であるgolang.org/x/crypto/sshに関する公式ドキュメント。
  • Gitのドキュメント: Gitのパッチ適用やリベースに関する一般的な概念理解のために参照。
  • Gerritのドキュメント: Gerritの仕組みとChange-IDに関する一般的な概念理解のために参照。