Repository: godotengine/godot
File: editor/scene_tree_dock.cpp (C++)

Code before:
			if (AnimationPlayerEditor::get_singleton()->get_track_editor()->get_root() == n) {
				undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton()->get_track_editor(), "set_root", n);
			}
			undo_redo->add_undo_method(this, "_set_owners", edited_scene, owners);
			undo_redo->add_undo_reference(n);

			EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
			undo_redo->add_do_method(ed, "live_debug_remove_and_keep_node", edited_scene->get_path_to(n), n->get_instance_id());
			undo_redo->add_undo_method(ed, "live_debug_restore_node", n->get_instance_id(), edited_scene->get_path_to(n->get_parent()), n->get_index(false));
		}
	}
	undo_redo->commit_action();

	// hack, force 2d editor viewport to refresh after deletion
	if (CanvasItemEditor *editor = CanvasItemEditor::get_singleton()) {
		editor->get_viewport_control()->queue_redraw();
	}

	_push_item(nullptr);

	// Fixes the EditorSelectionHistory from still offering deleted notes
	EditorSelectionHistory *editor_history = EditorNode::get_singleton()->get_editor_selection_history();
	editor_history->cleanup_history();
	InspectorDock::get_singleton()->call("_prepare_history");
}

void SceneTreeDock::_update_script_button() {
	if (!profile_allow_script_editing) {
		button_create_script->hide();
		button_detach_script->hide();
	} else if (editor_selection->get_selection().size() == 0) {
		button_create_script->hide();
		button_detach_script->hide();
	} else if (editor_selection->get_selection().size() == 1) {
		Node *n = editor_selection->get_selected_node_list()[0];
		if (n->get_script().is_null()) {
			button_create_script->show();
			button_detach_script->hide();
		} else {
			button_create_script->hide();
			button_detach_script->show();
		}
	} else {
		button_create_script->hide();
		Array selection = editor_selection->get_selected_nodes();
		for (int i = 0; i < selection.size(); i++) {
			Node *n = Object::cast_to<Node>(selection[i]);
			if (!n->get_script().is_null()) {
				button_detach_script->show();
				return;
			}

Review comment (suggestion):
I think this method and the one below could be merged. You don't need transform and name arrays, as noted in comments above, and paths can be empty when reparenting to root. Though maybe I'm missing something.

Code after:
		Array owned_nodes_array;
		Array paths_array;
		Array transform_array;
		Array name_array;

		for (Node *owned_node : owned) {
			if (owned_node != p_node && owned_node != edited_scene && owned_node->get_owner() == edited_scene && owned_node->get_parent()->get_owner() != edited_scene) {
				owned_nodes_array.push_back(owned_node);
				paths_array.push_back(p_node->get_path_to(owned_node->get_parent()));
				name_array.push_back(owned_node->get_name());
				Node3D *node_3d = Object::cast_to<Node3D>(owned_node);
				if (node_3d) {
					transform_array.push_back(node_3d->get_transform());
				} else {
					Node2D *node_2d = Object::cast_to<Node2D>(owned_node);
					if (node_2d) {
						transform_array.push_back(node_2d->get_transform());
					} else {
						transform_array.push_back(Variant());
					}
				}
			}
		}

		if (!owned_nodes_array.is_empty()) {
			undo_redo->add_undo_method(this, "_reparent_nodes_to_paths_with_transform_and_name", p_node, owned_nodes_array, paths_array, transform_array, name_array, edited_scene);
			undo_redo->add_do_method(this, "_reparent_nodes_to_root", p_node, owned_nodes_array, edited_scene);
		}
	}

	undo_redo->add_undo_method(Node3DEditor::get_singleton(), "update_all_gizmos", p_node);
	undo_redo->add_do_method(Node3DEditor::get_singleton(), "update_all_gizmos", p_node);

	undo_redo->add_undo_method(scene_tree, "update_tree");
	undo_redo->add_do_method(scene_tree, "update_tree");

	undo_redo->commit_action();
}

void SceneTreeDock::_delete_confirm(bool p_cut) {
	List<Node *> remove_list = editor_selection->get_selected_node_list();

	if (remove_list.is_empty()) {
		return;
	}

	bool entire_scene = false;

	for (const Node *E : remove_list) {
		if (E == edited_scene) {
			entire_scene = true;